/* =====================================================================
     Design tokens — one palette, two skins. Every colour below is a
     variable so light and dark stay in lockstep.
     Accent sits in a single violet hue family, the way mem0 does it:
     #9b8dff on the dark skin, #cbb2ff on the light skin — mem0's own two
     violet tokens, so the two sites read as neighbours.
     ===================================================================== */
  :root,
  html[data-theme="dark"]{
    /* Palette lifted from mem0.ai's own tokens: #9b8dff is its dark-skin
       accent, #0d0c14 its canvas, #f3f2fa its foreground. */
    --canvas:#0A0A0C;
    --surface:#121214;
    --surface-2:#1A1A1D;
    --surface-3:#232326;
    --fg:#F3F2FA;
    --fg2:#A1A1AA;
    --fg3:#71717A;
    --faint:#3F3F46;
    --accent:#C4B5FD;
    --accent-ink:#DDD6FE;
    --accent-deep:#A78BFA;
    --accent-bg:rgba(203,178,255,.10);
    --accent-line:rgba(203,178,255,.30);
    /* #cbb2ff is mem0's hero accent — it paints solid blocks (chips, bars,
       icon plates) in both skins, so it gets its own token */
    --accent-solid:#C4B5FD;
    --accent-solid-ink:#1B1727;
    --hair:rgba(255,255,255,.08);
    --hair-hi:rgba(255,255,255,.20);
    --aura:rgba(196,181,253,.05);
    --aura-2:rgba(255,255,255,.030);
    --mote:196,181,253;
    --mote-a:.16;
    --ok:#4ADE80;
    --gh-bg:#1C1A2A;
    --gh-line:rgba(255,255,255,.12);
    --gh-fg:#F3F2FA;
    --gh-count-bg:#232134;
    /* the code window is intentionally dark in both skins — a terminal reads
       as a device, and every serious dev site does the same */
    --code-bg:#100E1A;
    --code-bar:#15131F;
    --code-line:rgba(255,255,255,.08);
    --code-fg:#E4E2F2;
    --tk-k:#CBB2FF; --tk-s:#C9D4E8; --tk-c:#5B5876; --tk-p:#A9A5BC;
    --shadow:0 26px 60px -34px rgba(0,0,0,.9);
  }

  html[data-theme="light"]{
    /* mem0's light skin: #fcfcfc canvas, #ffffff cards, #020202 text,
       #565553 secondary, #cbb2ff accent. */
    --canvas:#FCFCFC;
    --surface:#FFFFFF;
    --surface-2:#F7F7FA;
    --surface-3:#F1F0F5;
    --fg:#020202;
    --fg2:#565553;
    --fg3:#A1A1AA;
    --faint:#D9D9D9;
    --accent:#CBB2FF;
    --accent-ink:#5B47B8;
    --accent-deep:#8B78F2;
    --accent-bg:rgba(203,178,255,.24);
    --accent-line:rgba(203,178,255,.60);
    --accent-solid:#CBB2FF;
    --accent-solid-ink:#1B1727;
    --hair:rgba(24,24,24,.10);
    --hair-hi:rgba(24,24,24,.22);
    --aura:rgba(203,178,255,.28);
    --aura-2:rgba(24,24,24,.016);
    --mote:120,100,190;
    --mote-a:.13;
    --ok:#16A34A;
    --gh-bg:#F6F8FA;
    --gh-line:#D0D7DE;
    --gh-fg:#24292F;
    --gh-count-bg:#FFFFFF;
    /* the code window's light tokens live in the "light skin" block below,
       next to the palette they belong to */
    --shadow:0 22px 48px -30px rgba(9,9,11,.22);
  }

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

  html{ scroll-behavior:smooth; scroll-padding-top:84px; -webkit-text-size-adjust:100%; background:var(--canvas); }
  html,body{ transition:background-color .28s ease, color .28s ease; }

  body{
    margin:0; background:var(--canvas); color:var(--fg);
    font-family:'Inter Variable',Inter,system-ui,-apple-system,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif;
    font-feature-settings:'cv11','ss01';
    -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
    overflow-x:hidden;
  }

  /* mem0 pairs Mona Sans (display) with Inter (body) and DM Mono (code). */
  h1,h2,h3,h4,.font-display,.metric,.btn,.tier-name,.num{
    font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,system-ui,-apple-system,'Segoe UI','PingFang SC',sans-serif;
  }

  ::selection{ background:var(--accent-bg); color:var(--fg); }
  ::-webkit-scrollbar{ width:11px; height:11px; }
  ::-webkit-scrollbar-track{ background:var(--canvas); }
  ::-webkit-scrollbar-thumb{ background:var(--surface-3); border-radius:99px; border:3px solid var(--canvas); }
  ::-webkit-scrollbar-thumb:hover{ background:var(--fg3); }

  .mono{ font-family:'DM Mono','JetBrains Mono',SFMono-Regular,Consolas,monospace; }
  a{ color:inherit; }
  button{ font-family:inherit; }
  /* The `hidden` attribute loses to any explicit `display`. Tailwind's
     `sm:inline-flex` on the header CTA beat it, so a signed-in visitor kept
     seeing “Start free” sitting next to their own account chip. */
  [hidden]{ display:none !important; }

  /* 响应式工具类的优先级护栏（2026-10-19 修）。
     `assets/tailwind.css` 在 <link> 里、排在本文档样式表之前，而组件样式
     给 .ghstar / .ctrl 直接写了 display:inline-flex。同特异性下后写的赢，
     于是 Tailwind 的 `.hidden` / `.xl\:hidden` 全部失效，后果是：
       · <640px 时顶栏同时挂着 GitHub + pip + 汉堡三套入口，把页面横向
         撑宽 210px（手机上整页可以左右拖）；
       · ≥1280px 时汉堡按钮反而关不掉，桌面端右侧多出一个用不上的按钮。
     这两条按断点把结论钉死。断点与 tailwind.config 保持一致：
     sm=640、xl=1280。 */
  @media (max-width:639.98px){ .hidden{ display:none !important; } }
  @media (min-width:1280px){ .xl\:hidden{ display:none !important; } }

  /* ------------------------------------------------------------ surfaces */
  #dust{ position:fixed; inset:0; width:100%; height:100%; z-index:0; display:block; pointer-events:none; }
  .aura{
    position:fixed; left:50%; top:-360px; transform:translateX(-50%);
    width:min(1500px,150vw); height:780px; z-index:0; pointer-events:none;
    background:radial-gradient(ellipse 46% 44% at 50% 50%, var(--aura) 0%, transparent 72%);
    filter:blur(16px);
  }
  .aura::after{
    content:''; position:absolute; left:50%; top:300px; transform:translateX(-50%);
    width:min(1100px,120vw); height:440px;
    background:radial-gradient(ellipse 50% 50% at 50% 50%, var(--aura-2) 0%, transparent 70%);
    filter:blur(34px);
  }
  .shell{ position:relative; z-index:2; padding-top:var(--hdr-h); }

  .hair-t{ border-top:1px solid var(--hair); }
  .hairline{ height:1px; background:var(--hair); }

  /* ---------------------------------------------------------------------
     Section headers, three shapes taken straight from mem0:
       .eyebrow     — small mono micro-label, for dense sub-headings
       .eyebrow-lg  — the big grey display label mem0 puts above a title
                      ("工作原理" over "添加任何内容。Mem0 会学习。")
       .pill        — the soft violet capsule used as a category chip
                      ("博客", "新算法")
     --------------------------------------------------------------------- */
  .eyebrow{ font-family:'DM Mono',monospace; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--fg3); }
  .eyebrow-lg{
    display:block;
    font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,sans-serif;
    font-size:clamp(22px,3.4vw,34px); font-weight:600;
    letter-spacing:-.02em; line-height:1.15; color:var(--fg3);
  }
  .pill{
    display:inline-flex; align-items:center; gap:7px;
    height:30px; padding:0 13px; border-radius:8px;
    background:var(--accent-bg); border:1px solid var(--accent-line);
    color:var(--accent-ink);
    font-size:12.5px; font-weight:600; letter-spacing:.005em; white-space:nowrap;
  }
  .pill .dot{ width:6px; height:6px; border-radius:50%; background:var(--accent); flex:none; }
  .pill-plain{ background:var(--surface); border-color:var(--hair); color:var(--fg2); }

  /* the little bordered square mem0 attaches to the right of a button label */
  .btn-ico{
    display:inline-flex; align-items:center; justify-content:center;
    width:22px; height:22px; border-radius:5px; flex:none; margin-left:2px;
    background:rgba(0,0,0,.10); border:1px solid rgba(0,0,0,.16);
  }
  .btn-ico svg{ width:12px; height:12px; }
  .btn-dark .btn-ico, .btn-onDark .btn-ico{
    background:rgba(255,255,255,.15); border-color:rgba(255,255,255,.26);
  }

  /* =====================================================================
     Vertical rhythm.

     国际通用 SaaS 的纵向节奏大致是：section 之间 80~112px，section 内部
     的块之间 32~48px，正文行距 1.6~1.8。原先是 section 9.5rem(152px)、
     块间 48px、`.pv-body` 底部 7rem(112px) —— 叠在内容页上就成了
     「关于我们」那种上下大片空白、内容被推到屏幕两头的观感。

     这里整体下调一档：section 7rem / 8rem，块间 38px，内容页底部 4.5rem。
     数值不是拍脑袋，是按「首屏标题与上一屏尾部的视觉距离不超过一个
     标题高度」反推的。
     ===================================================================== */
  .section-pad{ padding-top:7rem; padding-bottom:7rem; }
  @media (min-width:640px){ .section-pad{ padding-top:8rem; padding-bottom:8rem; } }

  /* Container width follows mem0's real endpoints — 1439.98px on desktop and
     809.98px on tablet. The 1200–1439 band is deliberately left unclamped:
     mem0's screenshots are taken at >=1440 where its box is effectively full
     bleed, and clamping the band below that is what made our header sit in a
     narrow centred column. !important is deliberate: the Tailwind CDN injects
     its own .max-w-shell at runtime, after this sheet, so nothing weaker wins. */
  @media (max-width:1199px){ .max-w-shell{ max-width:809.98px !important; } }
  /* the hero code window keeps mem0's 1100px content measure */
  /* 这三条都是实测踩出来的，不是装饰：
     ① min-width:0 —— grid 子项默认 min-width:auto，而 .term 里是
        white-space:pre 的代码块，它的最小内容宽度（~490px）会反过来把所在的
        网格列撑宽。
     ② width:100% —— #proof-body 是 grid，.term 是它的第二列。grid item 的
        stretch 会被 margin-left/right:auto 打断（auto margin 吃掉了全部剩余
        空间），item 于是退回 max-content 宽度 = 534px，而列只有 365px
        （1024 视口）/ 350px（390 视口），整页被撑出 30px / 164px。
        显式给 width:100%，auto margin 没有剩余空间可吃，宽度就锁在列宽上。
     ③ 溢出交给 .term-body 的 overflow-x:auto 吃掉，代码照旧可以横向滚。 */
  .term{ max-width:1100px; width:100%; margin-left:auto; margin-right:auto; min-width:0; }

  /* 顶栏在 1280–1439 这段最挤：logo（251px）+ 5 个菜单 + 6 个右侧控件。
     未登录多一个「登录」后实测溢 6px。把菜单间隙从 6px 收到 4px，
     5 个间隙省 10px —— 视觉上几乎看不出来，但刚好够。 */
  @media (min-width:1280px) and (max-width:1439.98px){ #mainnav{ gap:4px !important; } }

  /* -------------------------------------------------------------- header */
  #hdr{
    position:fixed; top:0; left:0; right:0; z-index:60; height:var(--hdr-h);
    border-bottom:1px solid transparent;
    transition:background .3s ease, border-color .3s ease;
  }
  #hdr.solid{
    background:color-mix(in srgb, var(--canvas) 78%, transparent);
    backdrop-filter:blur(14px) saturate(160%);
    -webkit-backdrop-filter:blur(14px) saturate(160%);
    border-bottom-color:var(--hair);
  }
  /* 顶栏间距：nav 容器 gap-0.5(2px) 太挤，菜单之间几乎没有呼吸感，
     国际化 SaaS 顶栏（mem0 / Linear / Vercel）普遍在 4~10px 之间。
     这里按钮 padding 0 14px + 容器 gap-1.5(6px)，两项一起调到约 8px 视觉间隔。 */
  .navbtn{
    display:inline-flex; align-items:center; gap:6px; height:38px; padding:0 16px;
    border-radius:9px; border:1px solid transparent; background:transparent;
    color:var(--fg2); font-size:14px; font-weight:450; cursor:pointer;
    transition:color .18s ease, background .18s ease;
  }
  .navbtn:hover{ color:var(--fg); background:var(--surface-2); }
  .navbtn[aria-expanded="true"]{ color:var(--fg); background:var(--surface-2); }
  .navbtn .chev{ width:13px; height:13px; opacity:.65; transition:transform .2s ease; }
  .navbtn[aria-expanded="true"] .chev{ transform:rotate(180deg); }
  /* 触屏/键盘可达：用 :focus-visible 补一条轮廓，避免只能靠鼠标操作 */
  .navbtn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

  /* Drop-down panels — header rows carry a label plus a one-line description,
     exactly the density mem0 uses; the Resources panel widens into a
     two-column list + featured card. */
  .menu{
    position:absolute; top:calc(100% + 8px); left:0; min-width:296px;
    padding:6px; border-radius:8px; display:none;
    background:var(--surface); border:1px solid var(--hair);
    box-shadow:var(--shadow); z-index:70;
  }
  /* 按钮与面板之间有 8px 视觉间隙，鼠标从按钮移向面板必然经过它。
     不填的话，指针在这 8px 里落在页头上，mouseout 就认为"离开了菜单"，
     140ms 后面板关闭 —— 表现就是「一下拉就消失，根本点不到」。
     这一条把空隙变成面板自己的命中区，视觉完全不变。 */
  .menu::before{
    content:''; position:absolute; left:0; right:0; top:-8px; height:8px;
  }
  .menu.on{ display:block; }
  .menu a{
    display:block; padding:9px 12px; border-radius:8px; text-decoration:none;
    color:var(--fg2); font-size:14px; line-height:1.35;
    transition:background .16s ease, color .16s ease;
  }
  .menu a:hover{ background:var(--surface-2); color:var(--fg); }
  .menu a .t{ display:block; font-weight:500; }
  .menu a .d{ display:block; margin-top:3px; font-size:12px; line-height:1.45; color:var(--fg3); }
  .menu a:hover .d{ color:var(--fg2); }

  .menu.wide{ min-width:452px; padding:8px; display:none; gap:8px; grid-template-columns:166px 1fr; }
  .menu.wide.on{ display:grid; }
  .menu.wide .col{ display:flex; flex-direction:column; gap:1px; }
  .menu.wide .col a{ padding:7px 10px; }
  .feat{
    border:1px solid var(--hair); border-radius:8px; overflow:hidden;
    background:var(--surface-2); display:flex; flex-direction:column; min-width:0;
  }
  .feat-art{
    padding:15px 12px; display:grid; grid-template-columns:1fr 1fr; gap:7px;
    border-bottom:1px solid var(--hair);
    background:linear-gradient(158deg, var(--surface-3), var(--surface-2));
  }
  .feat-tile{
    border:1px solid var(--hair); border-radius:6px; padding:9px 7px;
    background:var(--canvas); text-align:center; min-width:0;
  }
  .feat-tile .n{ display:block; font-family:'DM Mono','JetBrains Mono',monospace; font-size:15px; letter-spacing:-.03em; color:var(--fg); }
  .feat-tile .u{ display:block; margin-top:3px; font-family:'DM Mono','JetBrains Mono',monospace; font-size:8px; letter-spacing:.09em; text-transform:uppercase; color:var(--fg3); }
  .feat-body{ padding:12px 13px 14px; }
  .feat-body h4{ margin:0; font-size:12.5px; font-weight:600; color:var(--fg); }
  .feat-body p{ margin:5px 0 0; font-size:11.5px; line-height:1.55; color:var(--fg3); }
  .rel{ position:relative; }

  /* ------------------------------------------------------------- buttons */
  .btn{
    display:inline-flex; align-items:center; justify-content:center; gap:9px;
    height:38px; padding:0 15px; border-radius:6px;
    font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,sans-serif;
    font-size:13.5px; font-weight:600; line-height:1;
    border:1px solid transparent; cursor:pointer; text-decoration:none;
    transition:background .2s ease, color .2s ease, border-color .2s ease, opacity .2s ease, transform .12s ease;
    white-space:nowrap;
  }
  .btn:active{ transform:translateY(1px); }
  .btn-primary{ background:var(--fg); color:var(--canvas); }
  .btn-primary:hover{ opacity:.88; }
  .btn-ghost{ background:var(--surface); color:var(--fg2); border-color:var(--hair); }
  .btn-ghost:hover{ color:var(--fg); border-color:var(--hair-hi); background:var(--surface-2); }
  .btn-quiet{ background:transparent; color:var(--fg3); border-color:transparent; padding:0 10px; }
  .btn-quiet:hover{ color:var(--fg); background:var(--surface-2); }
  .btn-lg{ height:44px; padding:0 18px; font-size:14.5px; border-radius:6px; }
  .btn-sm{ height:32px; padding:0 12px; font-size:12.5px; border-radius:6px; }
  /* mem0's signature pairing: soft violet fill under a near-black label */
  .btn-accent{ background:var(--accent-solid); color:var(--accent-solid-ink); }
  .btn-accent:hover{ filter:brightness(1.05); }
  .btn-dark{ background:#1B1727; color:#F3F2FA; }
  .btn-dark:hover{ background:#2A2440; }

  /* control cluster (theme / language) */
  .ctrl{
    display:inline-flex; align-items:center; justify-content:center;
    width:32px; height:32px; border-radius:8px;
    border:1px solid transparent; background:transparent;
    color:var(--fg2); cursor:pointer; transition:color .18s ease, background .18s ease;
  }
  .ctrl:hover{ color:var(--fg); background:var(--surface-2); }
  .ctrl[aria-expanded="true"]{ color:var(--fg); background:var(--surface-2); }
  .ctrl svg{ width:16px; height:16px; }
  .pop{
    position:absolute; top:calc(100% + 10px); right:0; min-width:180px;
    padding:6px; border-radius:8px; display:none; z-index:80;
    background:var(--surface); border:1px solid var(--hair); box-shadow:var(--shadow);
  }
  .pop.on{ display:block; }
  .pop button{
    display:flex; align-items:center; gap:10px; width:100%;
    padding:8px 10px; border-radius:8px; border:0; background:transparent;
    color:var(--fg2); font-size:13px; text-align:left; cursor:pointer;
    transition:background .16s ease, color .16s ease;
  }
  .pop button:hover{ background:var(--surface-2); color:var(--fg); }
  .pop button svg{ width:15px; height:15px; color:var(--fg3); }
  .pop button .tick{ margin-left:auto; width:14px; height:14px; color:var(--accent); opacity:0; }
  .pop button[aria-checked="true"]{ color:var(--fg); }
  .pop button[aria-checked="true"] .tick{ opacity:1; }
  .pop .sep{ height:1px; background:var(--hair); margin:5px 4px; }
  .pop .cap{ padding:7px 10px 4px; font-family:'DM Mono','JetBrains Mono',monospace; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--fg3); }

  /* GitHub star widget — mirrors the counter style devs already know */
  .ghstar{
    display:inline-flex; align-items:stretch; height:32px; border-radius:8px;
    border:1px solid var(--gh-line); background:var(--gh-bg); color:var(--gh-fg);
    text-decoration:none; overflow:hidden; font-size:12.5px; font-weight:600;
  }
  .ghstar > span{ display:inline-flex; align-items:center; gap:6px; padding:0 10px; }
  .ghstar .lbl{ /* divider dropped along with the star count */ }
  .ghstar .cnt{ background:var(--gh-count-bg); font-family:'DM Mono','JetBrains Mono',monospace; font-weight:500; }
  .ghstar:hover{ border-color:var(--hair-hi); }
  .ghstar svg{ width:14px; height:14px; fill:currentColor; }

  /* --------------------------------------------------- announcement bar */
  .announce{
    position:relative; z-index:40; margin-top:0;
    background:var(--accent-bg); border-bottom:1px solid var(--accent-line);
  }
  .announce.off{ display:none; }
  .announce .in{
    max-width:1439.98px; margin:0 auto; padding:9px 46px;
    display:flex; align-items:center; justify-content:center; gap:12px;
    font-size:12.5px; color:var(--fg2); text-align:center;
  }
  .announce .in b{ color:var(--fg); font-weight:500; }
  .announce .cta{
    flex:none; display:inline-flex; align-items:center; height:25px; padding:0 10px;
    border-radius:6px; background:var(--fg); color:var(--canvas);
    font-size:11.5px; font-weight:600; text-decoration:none; white-space:nowrap;
  }
  .announce .x{
    position:absolute; right:14px; top:50%; transform:translateY(-50%);
    width:26px; height:26px; border-radius:6px; border:0; background:transparent;
    color:var(--fg3); cursor:pointer; display:inline-flex; align-items:center; justify-content:center;
  }
  .announce .x:hover{ color:var(--fg); background:var(--surface-2); }
  .announce .x svg{ width:14px; height:14px; }

  /* footer social glyphs */
  .foot-ic{
    display:inline-flex; align-items:center; justify-content:center;
    width:34px; height:34px; border-radius:8px;
    border:1px solid var(--hair); color:var(--fg3);
    transition:color .18s ease, border-color .18s ease, background .18s ease;
  }
  .foot-ic:hover{ color:var(--fg); border-color:var(--hair-hi); background:var(--surface-2); }
  .foot-ic svg{ width:16px; height:16px; }

  /* ---- footer --------------------------------------------------------
     mem0 ends its pages with a single solid violet block instead of yet
     another white band — it is the cheapest, most recognisable way to give
     the page a bottom edge. Same move for the light skin; the dark skin
     keeps a raised near-black so the page does not finish on a bright slab. */
  .site-foot{ background:var(--surface-2); }
  html[data-theme="light"] .site-foot{ background:#CBB2FF; }
  html[data-theme="light"] .site-foot .text-fg{ color:#1B1727; }
  html[data-theme="light"] .site-foot .text-fg2{ color:#3E3560; }
  html[data-theme="light"] .site-foot .text-fg3,
  html[data-theme="light"] .site-foot .text-faint{ color:#5C4F86; }
  html[data-theme="light"] .site-foot .hair-t,
  html[data-theme="light"] .site-foot .hairline{ border-color:rgba(27,23,39,.18); }
  html[data-theme="light"] .site-foot .foot-ic{ color:#1B1727; border-color:rgba(27,23,39,.20); background:rgba(255,255,255,.42); }
  html[data-theme="light"] .site-foot .foot-ic:hover{ color:#1B1727; background:rgba(255,255,255,.76); }
  html[data-theme="light"] .site-foot .tagbox2{ color:#3E3560; border-color:rgba(27,23,39,.22); }
  html[data-theme="light"] .site-foot a:hover{ color:#120F1C; }
  @media (max-width:640px){ .announce .in{ padding:9px 40px; font-size:11.5px; } .announce .in .hide-sm{ display:none; } }

  /* ------------------------------------------- hero pill group (mem0 style) */
  .pageseg{
    display:inline-flex; align-items:center; gap:2px; padding:3px;
    border:1px solid var(--hair); border-radius:8px; background:var(--surface);
  }
  .pageseg a{
    display:inline-flex; align-items:center; gap:7px; height:32px; padding:0 13px;
    border-radius:8px; text-decoration:none; color:var(--fg2);
    font-size:12.5px; transition:background .16s ease, color .16s ease;
  }
  .pageseg a:hover{ background:var(--surface-2); color:var(--fg); }
  .pageseg a svg{ width:14px; height:14px; }

  /* ------------------------------------------------------ routed page views */
  #home.off{ display:none; }
  #view[hidden]{ display:none; }
  .pv-hero{ padding:48px 0 0; text-align:center; }
  /* `.back` is shared by the content pages, the sign-in card and the console,
     so it is declared unscoped. Scoped to `.pv-hero` its icon carried no size
     rule on the account routes and rendered at the SVG default — a
     screen-filling chevron that pushed the sign-in card out of view. */
  .back{
    display:inline-flex; align-items:center; gap:7px; margin-bottom:22px;
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:11px; letter-spacing:.1em;
    text-transform:uppercase; color:var(--fg3); text-decoration:none;
  }
  .back:hover{ color:var(--fg); }
  .back svg{ width:13px; height:13px; flex:none; }
  .pv-h1{
    margin:18px 0 0; font-size:clamp(1.95rem,4.4vw,3.15rem); line-height:1.12;
    letter-spacing:-.032em; font-weight:700; color:var(--fg);
  }
  .pv-lede{ margin:17px auto 0; max-width:44rem; font-size:15px; line-height:1.72; color:var(--fg2); }
  .pv-cta{ margin-top:28px; display:flex; flex-wrap:wrap; gap:11px; justify-content:center; }
  /* 内容页（关于我们 / 定价 / 公司…）的纵向节奏。
     底部 7rem 留白让最后一屏看起来像被截断，收到 4.5rem。 */
  .pv-body{ padding:34px 0 3.5rem; }

  /* =====================================================================
     Account surface — sign-in / sign-up, and the console behind them.

     Same system as the rest of the site (violet #CBB2FF accent, 8px radius,
     Mona Sans headings) so the account area reads as part of the product
     rather than a bolted-on widget.
     ===================================================================== */
  .authwrap{ display:flex; justify-content:center; padding:44px 0 6.5rem; }
  .authcard{
    width:100%; max-width:456px; background:var(--surface);
    border:1px solid var(--hair); border-radius:8px; padding:30px 30px 26px;
  }
  .authtabs{ display:flex; gap:4px; padding:4px; background:var(--surface-2); border-radius:8px; margin-bottom:22px; }
  .authtabs button{
    flex:1; height:34px; border:0; background:transparent; border-radius:6px;
    font:inherit; font-size:13px; font-weight:500; color:var(--fg3); cursor:pointer;
    transition:background .18s ease, color .18s ease;
  }
  .authtabs button[aria-selected="true"]{ background:var(--surface); color:var(--fg); }
  .field{ margin-bottom:14px; }
  .field label{ display:block; font-size:12px; font-weight:500; color:var(--fg2); margin-bottom:6px; }
  .field input{
    width:100%; height:40px; padding:0 12px; font:inherit; font-size:13.5px;
    color:var(--fg); background:var(--canvas); border:1px solid var(--hair);
    border-radius:6px; outline:none;
    transition:border-color .18s ease, box-shadow .18s ease;
  }
  .field input:focus{ border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-bg); }
  .field input::placeholder{ color:var(--faint); }
  .field .hint{ margin-top:6px; font-size:11.5px; line-height:1.5; color:var(--fg3); }
  .fieldrow{ display:flex; gap:10px; align-items:flex-start; }
  .fieldrow .field{ flex:1; min-width:0; }
  .fieldrow input{ flex:1; min-width:0; }
  /* the inline "send code" control that rides beside the code field */
  .ghostbtn{
    flex:none; height:40px; padding:0 13px; border-radius:6px; border:1px solid var(--hair);
    background:var(--surface-2); color:var(--fg2); font:inherit; font-size:12.5px;
    cursor:pointer; white-space:nowrap;
    transition:border-color .18s ease, color .18s ease;
  }
  .ghostbtn:hover:not(:disabled){ border-color:var(--hair-hi); color:var(--fg); }
  .authmsg{
    margin:0 0 14px; padding:10px 12px; border-radius:6px; font-size:12.5px; line-height:1.55;
    border:1px solid var(--hair); background:var(--surface-2); color:var(--fg2);
  }
  .authmsg.err{ border-color:rgba(248,113,113,.42); background:rgba(248,113,113,.09); color:#F87171; }
  .authmsg.ok{ border-color:rgba(74,222,128,.38); background:rgba(74,222,128,.09); color:#4ADE80; }
  html[data-theme="light"] .authmsg.err{ color:#DC2626; }
  html[data-theme="light"] .authmsg.ok{ color:#15803D; }
  /* A toast lives outside the routed views on purpose: signing in repaints the
     page immediately, and anything drawn inside the login card is wiped by
     that repaint — which is why a successful sign-in used to look like
     nothing happened at all. */
  #mn-toast{
    position:fixed; left:50%; bottom:26px; z-index:95; pointer-events:none;
    transform:translate(-50%,14px); opacity:0; max-width:min(92vw,540px);
    padding:11px 17px; border-radius:8px; text-align:center;
    background:var(--fg); color:var(--canvas); font-size:13px; line-height:1.5;
    box-shadow:var(--shadow); transition:opacity .22s ease, transform .22s ease;
  }
  #mn-toast.on{ opacity:1; transform:translate(-50%,0); }

  /* 未登录点「Mnemosyne OS SaaS」弹出的登录提示。
     为什么用弹窗而不是直接跳 #/login：顶部菜单是**营销入口**，访客点它时
     往往还没决定要不要注册；一上来把人甩进登录表单，"了解产品"就变成了
     "先交账号"，转化和体验都更差。弹窗只说清一件事：这一块要登录后才能用，
     并给两个出口（注册 / 登录），不再合成一个按钮。
     2026-10-24 站长要求：删掉「还没有账号可以直接注册」那句，把「登录 / 注册」
     拆成两枚 ——「注册」白底、「登录」紫罗兰（站点主色）。
     理由是合成按钮的落点取决于上一次的 authTab：想注册的人点下去
     可能落在登录表单上，还得自己再找切换链接。 */
  #mn-login-gate{
    position:fixed; inset:0; z-index:140; display:none;
    background:rgba(5,5,10,.55); backdrop-filter:blur(3px);
    padding:16px; align-items:center; justify-content:center;
  }
  #mn-login-gate.on{ display:flex; }
  #mn-login-gate .gate-box{
    width:100%; max-width:430px; background:var(--surface);
    border:1px solid var(--hair-hi); border-radius:12px;
    box-shadow:var(--shadow); padding:22px 22px 18px;
  }
  #mn-login-gate h3{
    margin:0 0 8px; font-size:16px; font-weight:650; letter-spacing:-.01em; color:var(--fg);
  }
  #mn-login-gate p{
    margin:0 0 16px; font-size:13px; line-height:1.7; color:var(--fg2);
  }
  #mn-login-gate .gate-act{ display:flex; gap:8px; flex-wrap:wrap; }
  #mn-login-gate .gate-act .btn{ flex:1 1 0; justify-content:center; }
  /* 🔴 2026-10-24 站长要求：两个出口拆开，不要再合成「登录 / 注册」。
     注册 = 白底（次要动作，但必须一眼看见是"可以注册"）；
     登录 = 主题紫罗兰（与站点主色一致，是已有账号的人的主路径）。
     两色都用主题变量推导，不写死色值 —— 亮/暗两套皮肤自动跟随。 */
  #mn-login-gate .gate-reg{
    background:#fff; color:#1B1727; border:1px solid rgba(24,24,24,.14);
  }
  #mn-login-gate .gate-reg:hover{ background:#F7F5FF; color:#1B1727; }
  #mn-login-gate .gate-login{
    background:var(--accent-solid); color:var(--accent-solid-ink);
    border:1px solid transparent;
  }
  #mn-login-gate .gate-login:hover{ opacity:.9; }
  .authcard button:disabled, .authcard input:disabled{ opacity:.5; cursor:not-allowed; }
  .authalt{ margin-top:18px; text-align:center; font-size:12.5px; line-height:1.7; color:var(--fg3); }
  .authalt button{
    background:none; border:0; padding:0; font:inherit; color:var(--accent-ink);
    cursor:pointer; text-decoration:underline; text-underline-offset:2px;
  }
  .authdiv{ display:flex; align-items:center; gap:10px; margin:18px 0 14px; color:var(--fg3); font-size:11.5px; }
  .authdiv::before, .authdiv::after{ content:''; flex:1; height:1px; background:var(--hair); }
  .sso{ display:flex; gap:8px; }
  .sso button, .sso a{
    flex:1; display:inline-flex; align-items:center; justify-content:center; gap:7px;
    height:38px; border:1px solid var(--hair); border-radius:6px; background:var(--surface-2);
    color:var(--fg2); font:inherit; font-size:12.5px; cursor:pointer; text-decoration:none;
    transition:border-color .18s ease, color .18s ease;
  }
  .sso button:hover:not(:disabled), .sso a:hover{ border-color:var(--hair-hi); color:var(--fg); }
  .sso svg{ width:15px; height:15px; flex:none; }

  /* the third-party session banner above the email form */
  .ghbar{
    display:flex; align-items:center; gap:10px; padding:11px 12px; margin-bottom:18px;
    border:1px solid var(--accent-line); background:var(--accent-bg); border-radius:6px;
  }
  .ghbar img{ width:26px; height:26px; border-radius:50%; flex:none; display:block; }
  .ghbar .tx{ min-width:0; flex:1; }
  .ghbar .nm{ display:block; font-size:13px; color:var(--fg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ghbar .sub{ display:block; font-size:11.5px; color:var(--fg3); margin-top:2px; }
  .ghbar button{
    flex:none; height:26px; padding:0 10px; border-radius:6px; border:1px solid var(--hair);
    background:var(--surface); color:var(--fg2); font:inherit; font-size:11.5px; cursor:pointer;
  }
  .ghbar button:hover{ color:var(--fg); border-color:var(--hair-hi); }

  /* the signed-in chip in the header */
  .mechip{
    display:inline-flex; align-items:center; gap:8px; height:32px; padding:0 10px 0 4px;
    border-radius:6px; border:1px solid var(--hair); background:var(--surface);
    color:var(--fg2); font-size:12.5px; cursor:pointer; max-width:180px;
    transition:border-color .18s ease, color .18s ease;
  }
  .mechip:hover{ border-color:var(--hair-hi); color:var(--fg); }
  .mechip .av{
    width:22px; height:22px; border-radius:4px; flex:none; display:flex;
    align-items:center; justify-content:center; font-size:11px; font-weight:600;
    background:var(--accent-bg); color:var(--accent-ink); border:1px solid var(--accent-line);
  }
  .mechip .nm{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .mechip .chev{ width:13px; height:13px; opacity:.6; flex:none; }
  .mechip[aria-expanded="true"]{ border-color:var(--hair-hi); color:var(--fg); }

  /* The account menu. Standard SaaS header pattern: the avatar opens a panel
     holding identity + console + settings + sign-out, instead of a chip that
     jumps straight to the console and hides sign-out inside it. Right-aligned
     so it can never run off the right edge of a narrow window. */
  .menu.right{ left:auto; right:0; min-width:254px; }
  .menu button.ma{
    display:block; width:100%; text-align:left; padding:9px 12px;
    border:0; border-radius:8px; background:transparent; color:var(--fg2);
    font:inherit; font-size:14px; line-height:1.35; cursor:pointer;
    transition:background .16s ease, color .16s ease;
  }
  .menu button.ma:hover{ background:var(--surface-2); color:var(--fg); }
  .menu .mhead{
    display:flex; align-items:center; gap:10px;
    padding:8px 12px 10px; margin-bottom:5px; border-bottom:1px solid var(--hair);
  }
  .menu .mhead .av{
    width:30px; height:30px; border-radius:6px; flex:none; display:flex;
    align-items:center; justify-content:center; font-size:12.5px; font-weight:600;
    background:var(--accent-bg); color:var(--accent-ink); border:1px solid var(--accent-line);
  }
  .menu .mhead .tx{ min-width:0; }
  .menu .mhead .nm2{
    display:block; font-size:13.5px; color:var(--fg);
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .menu .mhead .em{
    display:block; font-size:11.5px; color:var(--fg3); margin-top:2px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* an inline note where an action button would be (e.g. the admin slot is taken) */
  .chipnote{ font-size:12px; color:var(--fg3); white-space:nowrap; }

  /* --------------------------------------------------------------- console */
  .console{ padding:38px 0 7rem; }
  .chead{ display:flex; flex-wrap:wrap; align-items:center; gap:14px; justify-content:space-between; }
  .cwho{ display:flex; align-items:center; gap:12px; min-width:0; }
  .cwho .av{
    width:40px; height:40px; border-radius:8px; flex:none; display:flex; align-items:center;
    justify-content:center; font-size:16px; font-weight:600; background:var(--accent-bg);
    color:var(--accent-ink); border:1px solid var(--accent-line);
  }
  .kgrid{ display:grid; grid-template-columns:repeat(2,1fr); gap:12px; }
  @media (min-width:768px){ .kgrid{ grid-template-columns:repeat(4,1fr); } }
  .kpi{ background:var(--surface); border:1px solid var(--hair); border-radius:8px; padding:18px; }
  .kpi .v{ font-size:30px; font-weight:700; letter-spacing:-.02em; line-height:1; color:var(--fg); }
  .kpi .l{ margin-top:9px; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--fg3); }
  .ktabs{ display:flex; flex-wrap:wrap; gap:2px; border-bottom:1px solid var(--hair); margin-top:32px; }
  .ktabs button{
    height:38px; padding:0 14px; border:0; background:none; font:inherit; font-size:13px;
    color:var(--fg3); cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px;
    transition:color .18s ease, border-color .18s ease;
  }
  .ktabs button:hover{ color:var(--fg2); }
  .ktabs button[aria-selected="true"]{ color:var(--fg); border-bottom-color:var(--accent); }
  .kpanel{ padding-top:22px; }
  .ltable{ width:100%; border-collapse:collapse; font-size:13px; }
  .ltable th, .ltable td{ padding:11px 12px; text-align:left; border-bottom:1px solid var(--hair); vertical-align:top; }
  .ltable th{ font-size:10.5px; letter-spacing:.12em; text-transform:uppercase; color:var(--fg3); font-weight:500; white-space:nowrap; }
  .ltable td{ color:var(--fg2); }
  .ltable td.strong{ color:var(--fg); }
  .ltable tr:last-child td{ border-bottom:0; }
  .st{ display:inline-flex; align-items:center; height:22px; padding:0 9px; border-radius:6px; font-size:11px; font-weight:500; white-space:nowrap; }
  .st.new{ background:var(--accent-bg); color:var(--accent-ink); border:1px solid var(--accent-line); }
  .st.done{ background:rgba(74,222,128,.1); color:#4ADE80; border:1px solid rgba(74,222,128,.32); }
  html[data-theme="light"] .st.done{ color:#15803D; }
  .st.muted{ background:var(--surface-2); color:var(--fg3); border:1px solid var(--hair); }
  .kempty{ padding:36px 20px; text-align:center; color:var(--fg3); font-size:13px; line-height:1.7; }

  /* =====================================================================
     Sub-page presentation, matched to mem0's interiors.

     mem0's About / Blog / Startup pages all lean on the same three devices:
     a tinted thumbnail plate at the top of a card, a centred pull-quote
     between sections, and a tinted block that holds a number. They are the
     reason its inner pages do not read as walls of text.
     ===================================================================== */

  /* the tinted plate mem0 puts above about / blog / startup cards */
  .thumb{
    aspect-ratio:16/10; border-radius:8px; overflow:hidden; position:relative;
    display:flex; align-items:center; justify-content:center; margin-bottom:16px;
  }
  .thumb .glyph{
    font-family:'DM Mono',monospace; font-size:10.5px; letter-spacing:.13em;
    text-transform:uppercase; padding:6px 12px; border-radius:6px;
    background:rgba(255,255,255,.34); color:#1B1727;
    max-width:86%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  .thumb-lav { background:#CBB2FF; }
  .thumb-ink { background:#141320; }
  .thumb-gold{ background:#F1C96C; }
  .thumb-mist{ background:#EDEBF5; }

  /* a card that carries a thumbnail above its text */
  .icard{ display:flex; flex-direction:column; }
  .icard h3{ margin:0; font-size:16.5px; font-weight:600; letter-spacing:-.014em; color:var(--fg); }
  .icard p{ margin:9px 0 0; font-size:13.5px; line-height:1.68; color:var(--fg2); }

  /* pull-quote, as used on mem0's about page */
  .pquote{ max-width:760px; margin:0 auto; text-align:center; }
  .pquote blockquote{
    margin:0; font-family:'Mona Sans Variable','Mona Sans',Inter,sans-serif;
    font-size:clamp(17px,2.2vw,22px); line-height:1.5; letter-spacing:-.014em; color:var(--fg);
  }
  .pquote .who{ margin-top:20px; display:flex; align-items:center; justify-content:center; gap:11px; }
  .pquote .who img{ width:38px; height:38px; border-radius:50%; object-fit:cover; border:1px solid var(--hair); flex:none; }
  .pquote .who .nm{ font-size:13.5px; color:var(--fg); font-weight:600; text-align:left; }
  .pquote .who .rl{ font-size:12px; color:var(--fg3); text-align:left; }

  /* job rows, from mem0's careers section */
  .jobs{ display:flex; flex-direction:column; gap:8px; }
  .job{
    display:flex; align-items:center; gap:14px; flex-wrap:wrap;
    padding:15px 17px; border:1px solid var(--hair); border-radius:8px;
    background:var(--surface); text-decoration:none;
    transition:border-color .22s ease, background .22s ease;
  }
  .job:hover{ border-color:var(--hair-hi); background:var(--surface-2); }
  .job .t{ font-size:14.5px; font-weight:600; color:var(--fg); }
  .job .m{ font-size:12.5px; color:var(--fg3); }
  .job .go{ margin-left:auto; font-size:12.5px; color:var(--accent-ink); white-space:nowrap; }

  /* blog index: category strip + search above a 2-up illustrated grid */
  .postbar{
    display:flex; align-items:center; gap:12px; flex-wrap:wrap;
    justify-content:space-between; margin-bottom:28px;
  }
  .postcats{ display:flex; gap:3px; flex-wrap:wrap; }
  .postcat{
    height:32px; padding:0 13px; border-radius:6px; border:1px solid transparent;
    background:transparent; color:var(--fg2); font-size:13px; font-weight:600;
    cursor:pointer; transition:background .18s ease, color .18s ease;
  }
  .postcat:hover{ color:var(--fg); background:var(--surface-2); }
  .postcat[aria-selected="true"]{ background:var(--fg); color:var(--canvas); }
  .postsearch{
    display:flex; align-items:center; gap:9px; padding:8px 12px;
    border:1px solid var(--hair); border-radius:8px; background:var(--surface);
    min-width:250px;
  }
  .postsearch svg{ width:15px; height:15px; color:var(--fg3); flex:none; }
  .postsearch input{ border:0; background:transparent; outline:none; font-size:13px; color:var(--fg); width:100%; }
  .postgrid{ display:grid; gap:30px 26px; grid-template-columns:1fr; }
  @media (min-width:760px){ .postgrid{ grid-template-columns:1fr 1fr; } }
  .post{ text-decoration:none; display:block; }
  .post h3{ margin:16px 0 0; font-size:17.5px; font-weight:600; line-height:1.32; letter-spacing:-.016em; color:var(--fg); }
  .post:hover h3{ color:var(--accent-ink); }
  .post .meta{ margin-top:9px; font-size:12.5px; color:var(--fg3); }
  .postempty{ margin-top:8px; font-size:13px; color:var(--fg3); }

  /* ------------------------------------------------------------------ *
   *  blog articles — a card per article: cover plate on the left, then the
   *  category, the headline, the lede and a read link. The cover is a real
   *  <img> (it is a supplied picture, not a generated tone), so it carries
   *  object-fit:cover instead of a flat background like .thumb above.
   * ------------------------------------------------------------------ */
  .agrid{ display:grid; gap:18px; grid-template-columns:1fr; margin-top:16px; }
  @media (min-width:820px){ .agrid{ grid-template-columns:1fr 1fr; } }
  .acard{
    display:flex; gap:16px; padding:14px; text-decoration:none;
    border:1px solid var(--hair); border-radius:10px; background:var(--surface);
    transition:border-color .22s ease, background .22s ease;
  }
  .acard:hover{ border-color:var(--hair-hi); background:var(--surface-2); }
  .athumb{
    flex:none; width:132px; aspect-ratio:16/10; border-radius:7px; overflow:hidden;
    display:flex; align-items:center; justify-content:center; background:var(--surface-2);
  }
  .athumb img{ width:100%; height:100%; object-fit:cover; display:block; }
  .abody{ display:flex; flex-direction:column; min-width:0; }
  .ameta{
    font-family:'DM Mono',monospace; font-size:10.5px; letter-spacing:.12em;
    text-transform:uppercase; color:var(--accent-ink);
  }
  .atitle{ margin-top:8px; font-size:15.5px; font-weight:600; line-height:1.38; letter-spacing:-.014em; color:var(--fg); }
  .acard:hover .atitle{ color:var(--accent-ink); }
  .alede{ margin-top:8px; font-size:13px; line-height:1.66; color:var(--fg2); }
  .amore{ margin-top:auto; padding-top:12px; font-size:12.5px; color:var(--accent-ink); }
  @media (max-width:520px){
    .acard{ flex-direction:column; }
    .athumb{ width:100%; aspect-ratio:16/9; }
  }

  /* the article itself: one narrow column, the cover on top, the text below */
  .pv-article .pv-h1{ max-width:46rem; margin-left:auto; margin-right:auto; }
  .pv-article .pv-lede{ max-width:44rem; }
  .pmeta{ margin-top:16px; text-align:center; font-size:12.5px; color:var(--fg3); }
  .artbody{ max-width:44rem; margin:0 auto; padding-bottom:40px; }
  .artcover{
    width:100%; aspect-ratio:16/9; object-fit:cover; object-position:50% 22%;
    border-radius:10px; border:1px solid var(--hair); display:block;
    background:var(--surface-2);
  }
  .arttext{
    margin:28px 0 0; padding:0; border:0; background:none;
    font-family:'Mona Sans Variable','Mona Sans',Inter,sans-serif;
    font-size:14.5px; line-height:1.85; color:var(--fg2); white-space:pre-wrap;
  }
  .arttext:first-letter{ color:var(--fg); }

  /* contact: the title on the left, the form in its own card on the right */
  .split{ display:grid; gap:44px; grid-template-columns:1fr; align-items:start; }
  @media (min-width:900px){ .split{ grid-template-columns:1fr 1fr; gap:60px; } }
  .formcard{ background:var(--surface); border:1px solid var(--hair); border-radius:10px; padding:26px; }

  .blk{ border-top:1px solid var(--hair); padding-top:22px; margin-top:30px; }
  .blk.first{ border-top:0; padding-top:0; margin-top:0; }
  .blk h2{ margin:0; font-size:clamp(1.2rem,2.3vw,1.6rem); font-weight:650; letter-spacing:-.022em; color:var(--fg); }
  .blk h2 + p{ margin-top:11px; }
  .blk h3{ margin:0; font-size:14.5px; font-weight:600; color:var(--fg); }
  .blk p{ margin:12px 0 0; max-width:52rem; font-size:13.8px; line-height:1.78; color:var(--fg2); }
  .blk ul{ margin:15px 0 0; padding:0; list-style:none; display:grid; gap:9px; }
  .blk ul li{ position:relative; padding-left:19px; font-size:13.4px; line-height:1.7; color:var(--fg2); }
  .blk ul li::before{
    content:''; position:absolute; left:1px; top:.66em;
    width:5px; height:5px; border-radius:50%; background:var(--brand-teal);
  }
  .blk ul li b{ color:var(--fg); font-weight:500; }
  .blk code{
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.3px; color:var(--fg);
    background:var(--surface-2); border:1px solid var(--hair); border-radius:5px; padding:1px 5px;
  }
  .note{
    margin-top:20px; padding:11px 15px; border-left:2px solid var(--accent-line);
    border-radius:0 9px 9px 0; background:var(--surface);
    font-size:12.4px; line-height:1.68; color:var(--fg3);
  }
  .note b{ color:var(--fg2); font-weight:500; }
  .note.warn{ border-left-color:var(--brand-slate-line); }

  .grid2, .grid3{ display:grid; gap:14px; grid-template-columns:1fr; margin-top:22px; }
  @media (min-width:700px){ .grid2{ grid-template-columns:1fr 1fr; } .grid3{ grid-template-columns:repeat(3,1fr); } }
  .mini{ border:1px solid var(--hair); border-radius:8px; padding:17px; background:var(--surface); }
  .mini:hover{ border-color:var(--hair-hi); }
  .mini .k{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--fg3); }
  .mini h3{ margin:9px 0 0; }
  .mini p{ margin:7px 0 0; max-width:none; font-size:12.4px; line-height:1.62; color:var(--fg3); }

  .codebox{ margin-top:20px; border:1px solid var(--hair); border-radius:8px; overflow:hidden; background:var(--code-bg); }
  .codebox .bar{ display:flex; align-items:center; height:36px; padding:0 13px; gap:9px; background:var(--code-bar); border-bottom:1px solid var(--code-line); }
  .codebox .bar .nm{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--code-fg); opacity:.6; }
  .codebox pre{ margin:0; padding:15px 16px; overflow-x:auto; }
  .codebox code{ padding:0; border:0; background:none; font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.4px; line-height:1.8; color:var(--code-fg); white-space:pre; }
  .codebox .cm{ color:var(--tk-c); }

  .toolrow{ border-top:1px solid var(--hair); padding:11px 0; display:grid; gap:3px 18px; grid-template-columns:250px 1fr; }
  .toolrow:first-of-type{ border-top:0; }
  .toolrow .nm{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.3px; color:var(--accent-ink); word-break:break-word; }
  /* 这里的 .ds 与文档站主容器 .ds 同名，而后者写着 min-height:100vh。
     不显式覆盖，每一个工具行的右列都会被撑成一整屏 —— 实测 about 页正文
     高 14666px、每条数据之间隔着 1000px 空白。主容器 .ds 的 background /
     color 也会一起漏过来，一并覆盖掉。 */
  .toolrow .ds{ font-size:13px; line-height:1.65; color:var(--fg2);
    min-height:0; height:auto; background:transparent; }
  @media (max-width:660px){ .toolrow{ grid-template-columns:1fr; gap:2px; } }

  .tiles{ display:grid; gap:12px; grid-template-columns:repeat(2,1fr); margin-top:26px; }
  @media (min-width:780px){ .tiles{ grid-template-columns:repeat(4,1fr); } }
  /* 原来写 background:var(--fg)——深色主题下恰好是白，浅色主题下直接变黑块，
     与全站配色无关。改成品牌紫罗兰（取自 logo 节点色 #4C3A8F），
     字色用极浅紫保对比（≥7:1）。 */
.tile{
    /* 🔴 2026-10-26：原来是 #5B41B8 → #3E2E8C 的深紫渐变，四块并排压得整页发黑，
       与页面其余浅色卡片不在一个重量级上。改成主题色系的极淡底 + 淡描边，
       数字用 accent-ink 提亮，深浅两套主题都靠变量走。 */
    background:var(--accent-bg);
    color:var(--fg); border-radius:12px; padding:18px 17px;
    border:1px solid var(--accent-line);
  }
.tile .n{ display:block; font-size:24px; font-weight:600; letter-spacing:-.03em; line-height:1.05; color:var(--accent-ink); }
.tile .l{ display:block; margin-top:7px; font-size:11.4px; line-height:1.4; color:var(--fg3); }

  .form{ margin-top:26px; border:1px solid var(--hair); border-radius:8px; background:var(--surface); padding:24px; }
  .form .f{ margin-bottom:16px; }
  .form .f:last-of-type{ margin-bottom:20px; }
  .form label{ display:block; margin-bottom:7px; font-size:12.4px; font-weight:500; color:var(--fg2); }
  .form input, .form textarea{
    width:100%; box-sizing:border-box; font-family:inherit; font-size:13.4px; color:var(--fg);
    background:var(--surface-2); border:1px solid var(--hair); border-radius:8px;
    padding:10px 12px; outline:none; transition:border-color .18s ease;
  }
  .form textarea{ min-height:106px; resize:vertical; line-height:1.62; }
  .form input:focus, .form textarea:focus{ border-color:var(--accent); }
  .form input::placeholder, .form textarea::placeholder{ color:var(--faint); }
  .form .ok{ margin-top:14px; font-size:12.5px; color:var(--ok); display:none; }
  .form .ok.on{ display:block; }

  .igsearch{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; margin-top:30px; padding:9px 13px; border:1px solid var(--hair); border-radius:8px; background:var(--surface); }
  .igsearch svg{ width:15px; height:15px; color:var(--fg3); flex:none; }
  .igsearch input{ flex:1 1 240px; min-width:0; background:transparent; border:0; outline:none; font-family:inherit; font-size:13px; color:var(--fg); }
  .igsearch input::placeholder{ color:var(--faint); }
  .igsearch select{ background:var(--surface-2); border:1px solid var(--hair); border-radius:8px; color:var(--fg2); font-family:inherit; font-size:12.4px; padding:6px 9px; outline:none; }
  .igcard{ border:1px solid var(--hair); border-radius:8px; background:var(--surface); padding:17px; display:flex; flex-direction:column; }
  .igcard:hover{ border-color:var(--hair-hi); }
  .igcard .hd{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
  .igcard .ic{
    width:30px; height:30px; border-radius:8px; border:1px solid var(--hair);
    background:var(--surface-2); display:flex; align-items:center; justify-content:center;
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.5px; color:var(--fg);
  }
  .igcard .go{ color:var(--fg3); text-decoration:none; font-size:15px; line-height:1; }
  .igcard .go:hover{ color:var(--fg); }
  .igcard h3{ margin:13px 0 0; font-size:13.8px; font-weight:600; color:var(--fg); }
  .igcard p{ margin:7px 0 0; flex:1; font-size:12.4px; line-height:1.62; color:var(--fg3); }
  .igcard .cp{
    margin-top:13px; align-self:flex-start; display:inline-flex; align-items:center; gap:7px;
    height:28px; padding:0 10px; border:1px solid var(--hair); border-radius:6px;
    background:transparent; color:var(--fg3); font-family:inherit; font-size:11.4px; cursor:pointer;
    transition:color .16s ease, border-color .16s ease;
  }
  .igcard .cp:hover{ color:var(--fg); border-color:var(--hair-hi); }
  .igcard .cp svg{ width:12px; height:12px; }
  .igempty{ margin-top:22px; font-size:13px; color:var(--fg3); }

  /* --------------------------------------------------------------- badge */
  .tag{
    display:inline-flex; align-items:center; height:22px; padding:0 8px; border-radius:6px;
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:10.5px; letter-spacing:.1em;
    text-transform:uppercase; color:var(--accent-ink);
    border:1px solid var(--accent-line); background:var(--accent-bg);
  }

  /* ----------------------------------------------------------- hero text */
  /* 主标题尺寸按「最长那一行」反推，不是拍脑袋定的。
     2026-10-19 文案换成 'From remembering conversations / to maintaining an
     evolving world model' 之后，原来的 7vw / 4.75rem 在 1440 宽下是 76px，
     两行各自又折成两行（实测 span 高 155px = 2 × 77.5px），看上去就是错行。
     实测这段文案在 100px 时宽 1743px → 1024 的容器最多 58px，746 的平板容器
     最多 42px。下面按这两个上限取 4vw / 3.55rem，两边都留了 3% 余量。
     text-wrap:balance 兜住窄屏：允许换行，但两行必须一样长，不留孤儿词。 */
  .h1{
    font-weight:600; font-size:clamp(1.85rem,4vw,3.55rem);
    line-height:1.08; letter-spacing:-.032em; margin:0; text-wrap:balance;
  }
  .h1 .l1{ display:block; color:var(--fg); }
  /* Solid colour, exactly like mem0. The previous gradient used
     background-clip:text, which renders as a full-width dark block whenever
     the engine does not clip — the headline's second line disappears behind it. */
  .h1 .l2{ display:block; color:var(--fg); }
  /* 中文只有 12 个字，同宽的容器能放到 4.2rem；但那会压过英文版的视觉重量
     —— 中文笔画密度更高，同字号看起来更大，实测 67px 在 1440 下显得突兀。
     收到 3.4rem（54px），与英文 57px 的视觉重量持平，两行也留出了呼吸。 */
  [data-lang="zh"] .h1{
    font-size:clamp(1.9rem,4.3vw,3.4rem); letter-spacing:-.02em; line-height:1.12;
  }
  /* text-wrap:pretty —— 长段落不用 balance（会强行让每行等长，读起来反而断气），
     只让浏览器把最后一行从「一个词」匀成正常长度。中文尤其明显：
     实测 1440 下末行只剩 119px（「重归你的掌控。」），pretty 会把它摊平。 */
  .lede{ font-size:1.0625rem; line-height:1.7; color:var(--fg2); max-width:46rem; margin:0; text-wrap:pretty; }
  .lede b{ color:var(--fg); font-weight:500; }
  /* hero 三块之间的呼吸间距。
     为什么不能写在 HTML 上的 mt-* 类里：.h1 与 .lede 自己声明了 margin:0，
     与 Tailwind 的 .mt-6/.mt-7 同特异性，而本文档样式表排在 tailwind.css 之后
     —— 后写者赢，mt-* 被静默吃掉。实测 pill 底边到 h1 顶边是 0px，
     这就是「三个框挤在一起」的真正原因。用 #top 提一级特异性，把间距钉在这里。 */
  #top .h1{ margin-top:2.5rem; }        /* 40px */
  #top .lede{ margin-top:2.25rem; }     /* 36px */
  #top .lede + div{ margin-top:2.75rem; } /* 44px，按钮行 */
  /* mem0 sets its section titles between 40 and 48px with tight tracking. */
  .h2{
    font-size:30px; font-weight:600; letter-spacing:-.028em; line-height:1.14; margin:0; color:var(--fg);
  }
  /* 标题折行统一交给浏览器平衡：允许换行，但各行长度必须接近，不留孤儿词。
     这一条覆盖全站 h1–h3（.h1/.h2/.h3 三个类名之外，还有大量直接写 <h2>/<h3>
     的区块标题，它们没有类名，只能靠标签选择器兜住）。Chrome 对超过 6 行的
     元素会自动忽略 balance，标题不会超，所以没有副作用。 */
  h1, h2, h3, .h1, .h2, .h3{ text-wrap:balance; }
  @media (min-width:640px){ .h2{ font-size:40px; } }
  /* 48px 是对标 mem0.ai 实测的 h2 阶梯（48 / line-height 52.8 / tracking -0.02em）。
     原来 46px 与自家 h1 的比例偏紧，区块标题压不住下方的三栏卡片。 */
  @media (min-width:1024px){ .h2{ font-size:48px; } }
  .sub{ font-size:16px; line-height:1.7; color:var(--fg2); margin:0; }
  .angle{ font-family:'DM Mono',monospace; color:var(--accent-ink); font-weight:400; }

  /* ------------------------------------------------------------ terminal */
  .term{ border:1px solid var(--code-line); border-radius:8px; overflow:hidden; background:var(--code-bg); box-shadow:var(--shadow); }
  .term-bar{
    display:flex; align-items:center; gap:14px; min-height:46px; padding:7px 14px;
    background:var(--code-bar); border-bottom:1px solid var(--code-line); flex-wrap:wrap;
  }
  .dots{ display:flex; gap:6px; flex:none; }
  .dots i{ width:9px; height:9px; border-radius:50%; background:#2A2A31; display:block; }
  .tab{
    height:27px; padding:0 11px; border-radius:6px; border:1px solid transparent;
    background:transparent; color:#7A7A88; font-family:'DM Mono',monospace;
    font-size:11.5px; cursor:pointer; transition:color .18s ease, background .18s ease;
  }
  .tab:hover{ color:#A9A5BC; background:rgba(255,255,255,.04); }
  .tab.on{ color:#F3F2FA; background:rgba(203,178,255,.16); }
  .term-body{ padding:20px 22px 24px; overflow-x:auto; }
  .term-body::-webkit-scrollbar{ height:8px; }
  .term-body::-webkit-scrollbar-thumb{ background:#2A2740; border-radius:8px; }
  pre.code{ margin:0; }
  code.code{
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.5px; line-height:1.9;
    white-space:pre; display:block; color:var(--code-fg);
  }
  .tk-k{ color:var(--tk-k); } .tk-s{ color:var(--tk-s); } .tk-c{ color:var(--tk-c); font-style:italic; }
  .tk-p{ color:var(--tk-p); } .tk-f{ color:#F3F2FA; } .tk-n{ color:#E4E2F2; }
  .pane{ display:none; } .pane.on{ display:block; }
  /* the code window keeps a dark skin in both themes, so its controls must use
     fixed terminal colours rather than the page tokens */
  #copy-btn{ color:#7A7A88; }
  #copy-btn:hover{ color:#F3F2FA; background:rgba(255,255,255,.06); }

  /* --------------------------------------------------------------- cards */
  .card{
    position:relative; background:var(--surface); border:1px solid var(--hair);
    border-radius:8px; transition:border-color .26s ease, background .26s ease;
  }
  .card:hover{ border-color:var(--hair-hi); }
  .card-pad{ padding:24px; }
  /* The soft violet plate behind a line icon — mem0's most repeated splash
     of colour, and the reason its cards do not read as flat grey boxes. */
  .ico{
    width:36px; height:36px; border-radius:8px; flex:none;
    border:1px solid var(--accent-line); background:var(--accent-bg);
    display:flex; align-items:center; justify-content:center; color:var(--accent-ink);
  }
  .ico svg{ width:17px; height:17px; stroke-width:1.8; }
  .metric{ font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,sans-serif; font-weight:600; letter-spacing:-.03em; line-height:1; }
  .metric-accent{ color:var(--accent-ink); }
  .k-label{ font-family:'DM Mono',monospace; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--fg3); }
  .rule{ height:1px; background:var(--hair); }

  /* --------------------------------------------------------- benchmarks
     mem0 draws its benchmark panel as flat CSS bars rather than with a
     chart library: solid violet fill on a pale track, value printed inside
     the fill, square corners. Copied so the two panels read alike.
     #9B8DFF is mem0's own deep-violet token. Each benchmark carries two
     bars here — ours against mem0's published score — so the comparison is
     the thing the reader sees first. */
  .legend-dot{ width:10px; height:10px; border-radius:3px; display:inline-block; flex:none; }

  .brow-group + .brow-group{ margin-top:22px; }
  .brow-group-label{
    font-family:'DM Mono',monospace; font-size:11px; letter-spacing:.13em;
    text-transform:uppercase; color:var(--fg3); margin-bottom:8px;
  }
  /* 🔴 2026-10-26：44px 高的直角条太重，压过了整页的正文。改成 26px 胶囊：
     圆角 999px、两行之间 7px、数值缩到 12.5px 并右对齐在条内。
     颜色由 JS 按基准组下发（--bc 实色 / --bcw 同色淡色），
     深色 = Mnemosyne OS，淡色 = Mem0。 */
  .brow{ position:relative; height:26px; border-radius:999px; background:var(--surface-3); overflow:hidden; }
  .brow + .brow{ margin-top:7px; }
  .brow-fill{
    position:absolute; top:0; bottom:0; left:0; border-radius:999px;
    background:var(--bc,#8B78F2);
    display:flex; align-items:center; justify-content:flex-end;
    padding:0 11px; transition:width .55s cubic-bezier(.2,.8,.2,1);
  }
  .brow-val{
    font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,sans-serif;
    font-size:12.5px; font-weight:600; letter-spacing:-.008em; color:#fff; white-space:nowrap;
  }
  .brow-them .brow-fill{ background:var(--bcw,rgba(120,120,140,.22)); }
  .brow-them .brow-val{ color:var(--fg2); }
  .step{
    border-top:1px solid var(--hair); padding-top:26px; position:relative;
  }
  .step .num{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:11.5px; color:var(--fg3); }

  /* ------------------------------------------------------------- tabs row */
  .seg{
    display:inline-flex; gap:4px; padding:4px; border-radius:8px;
    border:1px solid var(--hair); background:var(--surface);
  }
  .seg button{
    height:30px; padding:0 13px; border-radius:8px; border:0; background:transparent;
    color:var(--fg3); font-size:12.5px; font-weight:500; cursor:pointer;
    transition:color .18s ease, background .18s ease;
  }
  .seg button:hover{ color:var(--fg2); }
  .seg button[aria-selected="true"]{ color:var(--fg); background:var(--surface-3); }

  /* --------------------------------------------------------- architecture */
  .layer{ display:grid; grid-template-columns:34px 1fr; gap:16px; padding:22px 0; border-top:1px solid var(--hair); }
  .layer:last-of-type{ border-bottom:1px solid var(--hair); }
  .layer .idx{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:11px; color:var(--fg3); padding-top:3px; }
  .layer h3{ margin:0; font-size:15px; font-weight:500; color:var(--fg); display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
  .layer h3 .tagbox{ font-family:'DM Mono','JetBrains Mono',monospace; font-size:10.5px; font-weight:400; color:var(--fg3); border:1px solid var(--hair); border-radius:5px; padding:2px 6px; }
  .layer p{ margin:9px 0 0; font-size:13.5px; line-height:1.72; color:var(--fg2); }
  code.inl{
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:12px; color:var(--fg);
    background:var(--surface-2); border:1px solid var(--hair); border-radius:5px; padding:1px 5px;
  }
  .wire{ border:1px solid var(--hair); border-radius:8px; background:var(--code-bg); padding:6px; }
  .wire svg{ display:block; width:100%; height:auto; }
  .wire-legend{ display:flex; gap:18px; flex-wrap:wrap; padding:14px 4px 0; font-family:'DM Mono','JetBrains Mono',monospace; font-size:10.5px; color:var(--fg3); }
  .wire-legend span{ display:inline-flex; align-items:center; gap:6px; }
  .wire-legend i{ width:14px; height:1px; background:#52525B; display:block; }
  .wire-legend i.dash{ height:0; border-top:1px dashed #52525B; background:none; }
  .wire-legend i.hot{ background:var(--accent-deep); }

  /* --------------------------------------------------- comparison table */
  table.spec{ width:100%; border-collapse:collapse; font-size:13.5px; }
  table.spec th, table.spec td{ padding:14px 16px; text-align:left; border-bottom:1px solid var(--hair); vertical-align:top; }
  table.spec thead th{ font-family:'DM Mono',monospace; font-size:10.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--fg3); font-weight:400; white-space:nowrap; }
  table.spec thead th.hl{ color:var(--fg); }
  table.spec td:first-child{ color:var(--fg3); }
  table.spec td{ color:var(--fg2); }
  table.spec td.hl{ color:var(--fg); }
  table.spec tbody tr:hover{ background:var(--surface-2); }
  table.spec tbody tr:last-child td{ border-bottom:none; }

  /* ---------------------------------------------------------- pricing
     Geometry read off mem0/pricing: 390px cards, tight padding, small
     radius, rows parted by a hairline. */
  /* ---------------------------------------------------------- pricing
     2026-10-24 重做。站长截图指出：四张卡"大小不统一"，不像商务报价单。
     根因是卡高由内容决定（Free 5 条特性 / 增值包 6 条），一排放四张就是
     四个不同高度，报价、按钮、特性列表的基线全错位。
     修法不是给每张卡写死高度（换语言/换文案就崩），而是让网格自己拉平：
       · #tiers 用 align-items:stretch + 每张卡 height:100%，同排必然等高；
       · 卡内用 flex:1 的弹性占位把"报价 + 按钮"钉在固定段，
         特性列表放在下方扩展区，长短差异只体现在这里；
       · 报价区与按钮加 min-height，四张卡的价目数字与 CTA 横向对齐；
       · 间距改为 8 的倍数节奏（24/16/12），圆角统一 12px，
         主推档用一圈 accent 描边 + 极淡渐变底，做出"推荐"的层次，
         而不是靠加粗边框把卡片撑变形。 */
  .tier{
    display:flex; flex-direction:column; background:var(--surface);
    border:1px solid var(--hair); border-radius:16px;
    padding:24px 24px 26px; height:100%; box-sizing:border-box;
    transition:border-color .26s ease, box-shadow .26s ease, transform .26s ease;
  }
  .tier:hover{
    border-color:var(--hair-hi);
    box-shadow:0 8px 28px rgba(8,8,16,.07);
    transform:translateY(-2px);
  }
  .tier-rec{
    border-color:var(--accent-line);
    /* 2026-10-26：去掉顶部紫色渐变。四张卡底色统一成 --surface，
       「最受欢迎」只靠描边 + 角标区分 —— 一深一浅看着不像同一组。 */
    background:var(--surface);
  }
  .tier-rec:hover{ border-color:var(--accent); }

  /* 报价区：数字与单位对齐，四张卡高度一致 */
  /* 🔴 2026-10-26 定价卡重构（去付款按钮 + 版式对齐参考稿）：
     标题行 → 描述 → 周期切换 → 价格 → 说明 → 分隔线 → 权益。
     desc / price / note 三段各给固定 min-height，四张卡不论文案长短，
     权益列表都从同一条基线开始。 */
  .tier-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
  .tier-badge{
    flex:none; height:22px; padding:0 9px; border-radius:999px;
    display:inline-flex; align-items:center;
    font-size:11px; font-weight:500; letter-spacing:.01em;
    color:var(--fg3); background:var(--surface-3); border:1px solid var(--hair);
  }
  .tier-rec .tier-badge{ color:var(--accent-ink); background:var(--accent-bg); border-color:var(--accent-line); }

  .tier-desc{ margin:8px 0 0; font-size:12.5px; line-height:1.6; color:var(--fg3); min-height:40px; }
  /* 卡内周期切换：把 pseg-sm 自带的 14px 下边距收掉，改由 .tier-seg 统一控高。
     否则有切换按钮的卡（Pro/Team）比没有的卡（Free/增值包）高 14px，
     价格和权益列表就跟着错开。 */
  .tier-seg{ margin-top:14px; min-height:30px; }
  .tier .pseg-sm{ margin:0; }

  .tier .tier-price{ display:flex; align-items:baseline; gap:5px; margin-top:12px; min-height:42px; }
  .tier-amt{
    font-family:'Mona Sans Variable','Mona Sans','Inter Variable',Inter,system-ui,sans-serif;
    font-size:36px; font-weight:600; letter-spacing:-.035em; line-height:1; color:var(--fg);
  }
  .tier-per{ font-size:12.5px; color:var(--fg3); }

  .tier .tier-note{ margin:8px 0 0; min-height:18px; font-size:11.5px; line-height:1.5; color:var(--fg3); }
  .tier-rule{ height:1px; background:var(--hair); margin:16px 0 14px; }
  /* 小标题（「包含 Free 全部功能，外加」）作为权益列表的首行渲染。
     它没有图标，所以列宽改成 1fr；字号/行高/内边距全部继承 .feat，
     这样四张卡的第一行永远在同一条基线上。 */
  .tier .feat.cap{ grid-template-columns:1fr; color:var(--fg3); }

  /* 特性列表：弹性扩展区，长短差异只在这里体现，不影响上方对齐 */
  .tier .tier-feats{
    flex:1 1 auto; margin:0; padding:0; list-style:none;
    display:flex; flex-direction:column; gap:1px;
  }

  /* 四张卡同排时留出等宽间距，窄屏自动落到两列/一列 */
  #tiers{ align-items:stretch; }
  .tier-name{ font-size:16px; font-weight:600; letter-spacing:-.01em; color:var(--fg); }
  .tagbox2{ font-family:'DM Mono',monospace; font-size:10.5px; color:var(--fg3); border:1px solid var(--hair); border-radius:5px; padding:3px 8px; white-space:nowrap; }

  /* 2026-10-23 计费切换控件。
     为什么要自己写而不是用 tailwind 类：这个站点的 tailwind.css 是**预构建**的，
     任意新增的工具类不会被生成，只有这里出现过的类才有样式。所以控件样式
     直接写在这里，类名用 pseg-* 避免与既有命名冲突。 */
  .pseg{
    display:inline-flex; align-items:center; gap:2px; padding:3px;
    background:var(--surface); border:1px solid var(--hair); border-radius:8px;
  }
  .pseg button{
    font:inherit; font-size:12.5px; line-height:1; padding:7px 13px;
    border:0; border-radius:6px; background:transparent; color:var(--fg3);
    cursor:pointer; transition:background .18s ease, color .18s ease; white-space:nowrap;
  }
  .pseg button:hover{ color:var(--fg); }
  .pseg button[aria-pressed="true"]{
    background:var(--fg); color:var(--surface); font-weight:600;
  }
  .pseg button:disabled{ opacity:.35; cursor:not-allowed; }
  /* 卡内的小号版本（月付/年付切换） */
  .pseg-sm{ margin:0 0 14px; }
  .pseg-sm button{ font-size:11.5px; padding:5px 10px; }
  .price-note{ font-size:11px; line-height:1.65; color:var(--fg3); margin-top:8px; }

  /* Feature rows. The tick used to sit at a hard-coded margin-top:3px, which
     slid off the first text line the moment the resolved font changed
     metrics — that is the misalignment that showed up in the screenshot.
     An em offset pins it to the line box instead, so it stays centred on
     the first line for any font, at any size. */
  /* flex-direction has to be re-declared here. The nav's featured card also
     carries .feat and sets flex-direction:column; at equal specificity that
     declaration survived, so every plan tick was stacked ABOVE its label
     instead of beside it — measured 27px apart (16px icon + 11px gap),
     which is the misalignment that showed up in the screenshot. */
  /* 🔴 2026-10-26：改用 grid 两列（图标 / 文本），这是「权益错行」的根治。
     原来的 flex 布局里，通用 .feat 规则还带着 border + 圆角 + 灰底，
     于是定价卡里每条权益都被套了一个小灰盒子，行高一不齐就看着错位。
     现在：显式清掉盒子的 border/background/radius，图标列固定 15px，
     文本列 minmax(0,1fr) —— 每条的文字左边缘都落在同一根竖线上，
     长文本在自己那一列里换行，永远推不动图标。 */
  .tier .feat{
    display:grid; grid-template-columns:15px minmax(0,1fr); align-items:start;
    gap:10px; padding:5px 0;
    border:0; background:none; border-radius:0; overflow:visible;
    font-size:12.8px; line-height:1.6; color:var(--fg2);
  }
  .tier .feat + .feat{ border-top:0; }
  .tier .feat svg{ width:15px; height:15px; flex:none; stroke-width:2.4; color:var(--accent-ink); margin-top:3px; }
  .tier .feat.dim{ color:var(--fg3); }
  .tier .feat.dim svg{ color:var(--faint); }

  /* ------------------------------------------------------- resource cards
     mem0's closing row is a coloured thumbnail plate over a headline and a
     meta line. Same shape here, carrying the repository's own artefacts —
     it is the one place on the page where a second hue (mem0's yellow) is
     allowed in, and it stops the bottom of the page going monochrome. */
  /* min-width:0 —— 卡片是 #res-grid 的 grid item，默认 min-width:auto 会让
     里面的长串（scripts/verify_recall_quality.py 这类无空格路径）把整张卡片
     和所在列一起撑宽，实测 1024 视口下 #res-grid 溢出 17px。 */
  .bcard{ display:flex; flex-direction:column; text-decoration:none; min-width:0; }
  .bcard .thumb{
    display:flex; align-items:center; justify-content:center;
    aspect-ratio:16/10; border-radius:8px; margin-bottom:18px; overflow:hidden;
    transition:filter .22s ease;
  }
  .bcard:hover .thumb{ filter:brightness(1.05); }
  .bcard .thumb-chip{
    font-family:'DM Mono',monospace; font-size:11px; letter-spacing:.13em;
    text-transform:uppercase; padding:5px 11px; border-radius:6px;
    background:rgba(255,255,255,.32); white-space:nowrap;
    max-width:88%; overflow:hidden; text-overflow:ellipsis;
  }
  /* overflow-wrap:anywhere —— 只在整行放不下时才断，正常单词不受影响；
     断不了的只有路径、URL、代码标识符这类超长无空格串，正是撑爆卡片的元凶。 */
  .bcard-t{ font-size:17px; font-weight:600; line-height:1.32; letter-spacing:-.015em; color:var(--fg); overflow-wrap:anywhere; }
  .bcard-d{ margin-top:9px; font-size:13.5px; line-height:1.65; color:var(--fg2); overflow-wrap:anywhere; }
  .bcard-m{ margin-top:auto; padding-top:14px; font-size:11.5px; color:var(--accent-ink); }

  /* ------------------------------------------------------------ reveal */
  .reveal{ opacity:0; transform:translateY(14px); transition:opacity .7s cubic-bezier(.2,.8,.2,1), transform .7s cubic-bezier(.2,.8,.2,1); }
  .reveal.in{ opacity:1; transform:none; }

  /* ------------------------------------------------------------ drawers */
  .sheet{
    position:fixed; inset:0; z-index:90; display:none; padding:20px; overflow-y:auto;
    background:color-mix(in srgb, var(--canvas) 97%, transparent);
    backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  }
  .sheet.on{ display:block; }
  .sheet summary{
    display:flex; align-items:center; justify-content:space-between;
    padding:15px 4px; font-size:16px; color:var(--fg); cursor:pointer;
    border-bottom:1px solid var(--hair); list-style:none;
  }
  .sheet summary::-webkit-details-marker{ display:none; }
  .sheet summary svg{ width:16px; height:16px; color:var(--fg3); transition:transform .2s ease; }
  .sheet details[open] summary svg{ transform:rotate(180deg); }
  .sheet details a{ display:block; padding:11px 4px 11px 16px; font-size:14px; color:var(--fg2); text-decoration:none; border-bottom:1px solid var(--hair); }
  .sheet details a:hover{ color:var(--fg); }

  /* ------------------------------------------------- brand lockup (logo)
     Reproduced 1:1 from brand/logo-horizontal-*.svg — viewBox 0 0 320 96,
     mark at translate(4,16), "mnemosyne" x=90 y=59 32px/600/-1,
     "OS" x=270 y=58 20px/400/+3.6. The viewBox below is cropped to the glyph
     box so the lockup fills its frame instead of floating in 96 units of
     padding — same geometry, larger apparent size. */
  html[data-theme="dark"]{
    --logo-line:#A9B8D6; --logo-inner:#66779F; --logo-outer:#A9B8D6;
    --logo-core:#5EEAD4; --logo-word:#FFFFFF; --logo-os:#8FA0C4;
  }
  html[data-theme="light"]{
    --logo-line:#94A3B8; --logo-inner:#5B6B8A; --logo-outer:#94A3B8;
    --logo-core:#0D9488; --logo-word:#0B1220; --logo-os:#64748B;
  }
  /* 页头高度只有一个来源。之前 #hdr 与 .shell 各自写死一个数字，
     我把页头改高之后就盖住了公告条 —— 现在两边都读 --hdr-h，
     以后只改这一个值，页头、公告条、锚点偏移一起走。 */
  html{ --hdr-h:76px; }
  @media (min-width:640px){ html{ --hdr-h:84px; } }
  #hdr{ height:var(--hdr-h); }
  .shell{ padding-top:var(--hdr-h); }
  /* 控制台与文档站没有页头，也就不该留出页头的位置 */
  body.dash .shell, body.docs .shell{ padding-top:0; }

  /* 两次调整后的尺寸：桌面端是原来的一半高，字号只放大不缩小；
     clamp 让窄屏按比例收，避免标志把导航挤出去。 */
  .logo{ display:block; height:clamp(38px, 3.9vw, 55px); width:auto; flex:none; margin-right:14px; }
  @media (max-width:639px){ .logo{ height:46px; } }
  /* Footer wordmark. At 72px the SVG resolved to ~328px of painted width
     while its column was capped at 252px, so it overran the first link
     column. mem0's own footer mark is ~32px — half of what we had. */
  .logo-lg{ height:36px; }
  @media (max-width:639px){ .logo-lg{ height:28px; } }
  .logo .lg-line{ stroke:var(--logo-line); stroke-width:1.35; stroke-opacity:.44; }
  .logo .lg-in{ fill:var(--logo-inner); }
  .logo .lg-out{ fill:var(--logo-outer); }
  .logo .lg-core{ fill:var(--logo-core); }
  .logo .lg-word, .logo .lg-os{ font-family:'Inter Variable',Inter,'Segoe UI','Helvetica Neue',Arial,sans-serif; }
  /* 字重从 600 提到可变字体的上限 900，再加一圈同色描边——
     光靠 900 到不了“两倍粗”，描边才让笔画真的变厚。
     字距从 -1.3px 收到 -0.2px：原来的负字距把 8 个字母挤成一坨，
     配合 textLength 一起放宽（见 SVG 里的 184），整体宽度不变、字母之间有缝。 */
  .logo .lg-word{ fill:var(--logo-word); font-size:32px; font-weight:900; letter-spacing:-.2px;
    stroke:var(--logo-word); stroke-width:1.05px; paint-order:stroke fill; }
  /* OS 与前面反着来：字距从 4px 收到 1px（原来像两个不相干的字母），
     字重提到 900、描边加厚到 1.05，让它作为后缀站得住。 */
  .logo .lg-os{ fill:var(--logo-os); font-size:32px; font-weight:900; letter-spacing:1px;
    stroke:var(--logo-os); stroke-width:1.05px; paint-order:stroke fill; }

  /* ----------------------------------------------------- integrations */
  .intg{
    display:flex; flex-direction:column; gap:11px; padding:20px;
    background:var(--surface); border:1px solid var(--hair); border-radius:8px;
    transition:border-color .26s ease;
  }
  .intg:hover{ border-color:var(--hair-hi); }
  .intg .tp{
    align-self:flex-start; font-family:'DM Mono','JetBrains Mono',monospace; font-size:10.5px;
    color:var(--fg3); border:1px solid var(--hair); border-radius:6px; padding:3px 8px;
    white-space:nowrap;
  }
  .intg .pth{
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:11px; color:var(--accent-ink);
    word-break:break-all; margin-top:auto;
  }
  .intg .pth.plain{ color:var(--fg3); }

  .skip{
    position:absolute; left:-9999px; top:0; z-index:200; padding:10px 16px;
    background:var(--fg); color:var(--canvas); border-radius:0 0 8px 0; font-size:13px;
  }
  .skip:focus{ left:0; }

  /* =====================================================================
     Ornament, and a light skin for the code window.

     mem0 ornaments with exactly one hue — its violet #CBB2FF — over a neutral
     grey scale. That is what gives its pages depth without turning them into a
     rainbow. The brand's own teal is retuned onto that same violet axis below,
     so every accent on the page (icon plates, section dots, step numbers, the
     wireframe packets, the footer block) belongs to one family, and the only
     contrast left doing work is light against dark.

     The code window used to be black in both skins. On a white page that read
     as a hole punched through the layout, so light mode gets a proper paper
     skin with the same restrained syntax palette.
     ===================================================================== */
  /* =====================================================================
     Account extras, the console's language switch, the brain graph host
     and the whole documentation shell. Appended at the end of the sheet so
     these rules win ties against the marketing styles above them.
     ===================================================================== */

  /* ---------------------------------------- avatars (header + profile) */
  .mechip .av img, .mhead .av img, .dx-ava img, .dx-me-av img{
    width:100%; height:100%; object-fit:cover; border-radius:inherit; display:block;
  }
  .dx-ava svg, .dx-me-av svg, .mechip .av svg, .mhead .av svg{
    width:62%; height:62%; display:block;
  }
  /* avatarHTML 总是在最外层容器里再套一个 span。那个 span 没有布局样式时，
     里面的标志会贴在左上角 —— 控制台右上角就是这样偏掉的。让内层撑满并居中，
     外层圆框只负责形状与配色。 */
  .dx-ava > span, .mechip .av > span, .mhead .av > span{
    display:flex; align-items:center; justify-content:center;
    width:100%; height:100%; border-radius:inherit; overflow:hidden;
  }
  /* The mark inherits currentColor; on the dark chip that has to be the accent,
     otherwise the default avatar reads as a black smudge. */
  .dx-ava, .dx-me-av{ color:#CBB2FF; }

  .avrow{ display:flex; align-items:center; gap:16px; margin:2px 0 18px; }
  .avprev{
    width:64px; height:64px; border-radius:50%; flex:none; overflow:hidden;
    display:flex; align-items:center; justify-content:center;
    background:var(--surface-2); border:1px solid var(--hair); color:var(--accent);
  }
  .avprev img{ width:100%; height:100%; object-fit:cover; display:block; }
  .avprev svg{ width:62%; height:62%; }
  .avmeta{ min-width:0; }
  .avmeta .t{ font-size:13.5px; color:var(--fg); display:block; }
  .avmeta .d{ font-size:12px; color:var(--fg3); display:block; margin-top:3px; line-height:1.5; }
  .avbtns{ display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
  .avbtn{
    display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 11px;
    border-radius:6px; border:1px solid var(--hair); background:var(--surface-2);
    color:var(--fg2); font:inherit; font-size:12px; cursor:pointer;
    transition:border-color .18s ease, color .18s ease;
  }
  .avbtn:hover{ border-color:var(--hair-hi); color:var(--fg); }
  .avbtn.dg{ color:#F87171; }
  .avbtn:disabled{ opacity:.5; cursor:default; }

  /* --------------------------------- console: language switch + graph host */
  .dx-lang{
    display:inline-flex; align-items:center; gap:2px; padding:2px; margin-right:8px;
    border:1px solid rgba(255,255,255,.10); border-radius:6px; background:rgba(255,255,255,.03);
  }
  .dx-lang button{
    height:24px; min-width:32px; padding:0 8px; border:0; border-radius:4px;
    background:transparent; color:#9C99B0; font:inherit; font-size:11.5px; cursor:pointer;
  }
  .dx-lang button.on{ background:rgba(255,255,255,.12); color:#F3F2FA; }

  .brn-host{
    position:relative; height:640px; margin-top:16px;
    border:1px solid rgba(255,255,255,.075); border-radius:10px; overflow:hidden;
    background:#05070D;
  }
  .brn-host .brn-note{
    position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
    flex-direction:column; gap:10px; text-align:center; padding:24px;
    color:#9C99B0; font-size:12.5px; line-height:1.7;
  }
  .brn-host .brn-note b{ color:#DED9F5; font-weight:500; font-size:13px; }
  @media (max-width:900px){ .brn-host{ height:460px; } }

  /* =====================================================================
     图谱渲染层的指针穿透补丁

     assets/brain.bundle.js 自带 CSS 里有三层 absolute 覆盖物没有声明
     pointer-events，于是它们各自吃掉覆盖区域的鼠标事件：

       .brn-legend  left/bottom   图例（纯展示）
       .brn-stats   right/top     节点/边计数（纯展示）
       .brn-msg     inset:0       居中提示（当前 JSX 未用到，但规则在）

     三层都不含任何可交互元素，本应让指针穿过去。实际效果是：图看得见、
     布局也在动，但鼠标移到左下图例、右上计数附近时 hover / 点击全部无
     反应 —— 节点恰恰最密的地方被一层看不见的玻璃盖住。

     为什么必须 !important：bundle 在运行时把自己的 CSS 追加到 <head> 末尾，
     晚于本样式表，同特异性下签到的规则输。这里补的是第三方产物的缺陷，
     不打算为了它去 fork 1.1 MB 的构建文件。
     ===================================================================== */
  .brn-legend, .brn-stats, .brn-msg { pointer-events:none !important; }
  /* 提示层若将来真的放按钮（比如"重试"），让按钮自己把事件收回来，
     而不是把整层的 pointer-events 再放开。 */
  .brn-msg button, .brn-msg a { pointer-events:auto !important; }

  /* 操作提示：图谱是 3D 点云，不给提示的话没人知道能拖、能滚、能悬停。
     这不是装饰 —— 「鼠标放上去没反应」有一半是「不知道可以放上去」。 */
  .brn-hint{
    display:flex; align-items:center; flex-wrap:wrap; gap:6px 14px;
    margin-top:14px; font-size:12px; color:var(--d-fg3);
  }
  .brn-hint span{ display:inline-flex; align-items:center; gap:6px; }
  .brn-hint kbd{
    font-family:'DM Mono',monospace; font-size:10.5px; padding:1px 5px;
    border:1px solid var(--d-line2); border-radius:4px; color:var(--d-fg2);
  }
  /* 可交互的视觉承诺：指针形状是最便宜的 affordance。
     注意不能只写 canvas —— 组件把 canvas 挂成 position:fixed 且
     pointer-events:none（three.js 的渲染层），指针实际落在它上面的
     .brn-root 上，canvas 的 cursor 永远不会生效。 */
  .brn-root, #brain-host canvas{ cursor:grab; }
  .brn-root:active, #brain-host canvas:active{ cursor:grabbing; }
  .brn-retry{ margin-left:10px; pointer-events:auto !important; }

  /* ---------------- 图谱关系面板 ---------------- */
  /* 三维画布点不开的关系，用二维列表补齐：左列节点（可搜），右列该节点的
     出边与邻居。同一份 /api/graph 数据，只是换了一种读得清的排法。 */
  .brn-rel{
    margin-top:14px; border:1px solid var(--d-line); border-radius:10px;
    background:var(--d-panel); overflow:hidden;
  }
  .brn-relbar{ display:flex; align-items:center; gap:10px; padding:10px 12px;
    border-bottom:1px solid var(--d-line); }
  .brn-relbar .inp{ max-width:280px; }
  .brn-relc{ margin-left:auto; font-size:11px; color:var(--d-fg3);
    font-family:'DM Mono',monospace; white-space:nowrap; }
  .brn-relbody{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.35fr); }
  @media (max-width:860px){ .brn-relbody{ grid-template-columns:1fr; } }
  .brn-nodes{ max-height:280px; overflow-y:auto; padding:8px;
    border-right:1px solid var(--d-line); }
  @media (max-width:860px){ .brn-nodes{ border-right:0; border-bottom:1px solid var(--d-line); } }
  .brn-node{
    display:flex; align-items:baseline; gap:8px; width:100%; text-align:left;
    padding:6px 9px; border:0; border-radius:6px; background:transparent;
    color:var(--d-fg2); font:inherit; font-size:12.5px; cursor:pointer;
  }
  .brn-node:hover{ background:rgba(255,255,255,.05); color:var(--d-fg); }
  .brn-node.on{ background:rgba(203,178,255,.14); color:var(--d-accent); }
  .brn-node .t{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .brn-node .k{ margin-left:auto; flex:none; font-size:10px; color:var(--d-fg3);
    font-family:'DM Mono',monospace; }
  .brn-detail{ padding:12px 14px; min-height:150px; }
  .brn-detailempty,.brn-empty{ font-size:12px; color:var(--d-fg3); line-height:1.7; }
  .brn-dhead{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap;
    padding-bottom:9px; margin-bottom:9px; border-bottom:1px solid var(--d-line); }
  .brn-dhead b{ font-size:14px; color:var(--d-fg); font-weight:600; }
  .brn-dhead span{ margin-left:auto; font-size:11px; color:var(--d-accent);
    font-family:'DM Mono',monospace; }
  .brn-edges{ display:flex; flex-direction:column; gap:5px; max-height:150px; overflow-y:auto; }
  .brn-edge{ display:flex; align-items:baseline; gap:8px; font-size:12px; }
  .brn-edge .d{ flex:none; width:14px; color:var(--d-fg3); text-align:center; }
  .brn-edge .n2{ color:var(--d-fg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .brn-edge .r{ margin-left:auto; flex:none; font-size:10.5px; color:var(--d-fg3);
    font-family:'DM Mono',monospace; }
  .brn-dsub{ margin-top:12px; font-size:11px; color:var(--d-fg3); }
  .brn-cloud{ display:flex; flex-wrap:wrap; gap:6px; margin-top:7px; }
  .brn-chip{ font-size:11px; padding:3px 8px; border-radius:5px;
    background:var(--d-panel2); border:1px solid var(--d-line); color:var(--d-fg2); }
  .brn-chip i{ font-style:normal; color:var(--d-fg3); font-family:'DM Mono',monospace; }

  /* 工具台：一列工具 + 展开的参数面板 */
  .dx-tool{ padding:10px 12px; border-radius:8px; cursor:pointer;
            border:1px solid transparent; transition:background .16s ease; }
  .dx-tool:hover{ background:rgba(255,255,255,.04); }
  .dx-tool.on{ background:rgba(123,97,255,.12); border-color:rgba(123,97,255,.4); }
  .dx-tool.off{ opacity:.55; cursor:default; }
  .dx-tool .nm{ font-size:13px; font-weight:550; font-family:var(--mono, ui-monospace, monospace); }
  .dx-tool .ds{ font-size:11.5px; color:#9C99B0; margin-top:4px; line-height:1.6;
                display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  .dx-toolpanel{ margin:6px 0 12px; padding:14px; border-radius:8px;
                 background:rgba(0,0,0,.22); border:1px solid rgba(255,255,255,.08); }
  .dx-trow{ display:flex; align-items:center; gap:12px; padding:6px 0; }
  .dx-trow .k{ width:150px; flex:none; font-size:12px; color:#9C99B0;
               font-family:var(--mono, ui-monospace, monospace); }
  .dx-trow .k.rq::after{ content:' *'; color:#ff8080; }

  /* ============================ documentation shell ==================== */
  .ds{ min-height:100vh; background:var(--canvas); color:var(--fg); }
  .ds-top{
    position:sticky; top:0; z-index:70; height:58px;
    background:color-mix(in srgb, var(--canvas) 88%, transparent);
    backdrop-filter:saturate(160%) blur(12px);
    -webkit-backdrop-filter:saturate(160%) blur(12px);
    border-bottom:1px solid var(--hair);
  }
  .ds-top-in{
    max-width:1440px; margin:0 auto; height:100%; padding:0 22px;
    display:flex; align-items:center; gap:16px;
  }
  .ds-logo{
    display:flex; align-items:center; gap:9px; text-decoration:none; color:var(--fg);
    font-size:14.5px; font-weight:650; letter-spacing:-.01em; flex:none;
  }
  .ds-logo svg{ width:24px; height:24px; color:var(--accent); }
  .ds-logo .tag{
    font-family:'DM Mono',monospace; font-size:10px; letter-spacing:.1em; text-transform:uppercase;
    color:var(--fg3); border-left:1px solid var(--hair); padding-left:9px; margin-left:3px;
  }
  .ds-sbtn{
    display:flex; align-items:center; gap:9px; height:34px; padding:0 12px;
    flex:1; max-width:440px; margin-left:auto;
    border:1px solid var(--hair); border-radius:7px; background:var(--surface);
    color:var(--fg3); font:inherit; font-size:13px; cursor:pointer; text-align:left;
  }
  .ds-sbtn:hover{ border-color:var(--hair-hi); }
  .ds-sbtn svg{ width:14px; height:14px; flex:none; }
  .ds-sbtn kbd{
    margin-left:auto; font-family:'DM Mono',monospace; font-size:10.5px; color:var(--fg3);
    border:1px solid var(--hair); border-radius:4px; padding:1px 5px; background:var(--surface-2);
  }
  .ds-dash{
    display:inline-flex; align-items:center; gap:7px; height:34px; padding:0 13px; flex:none;
    border-radius:7px; background:var(--accent); color:#141026;
    font-size:12.5px; font-weight:550; text-decoration:none; white-space:nowrap;
  }
  .ds-dash:hover{ opacity:.9; }
  .ds-dash svg{ width:13px; height:13px; }
  .ds-lbtn{
    height:34px; padding:0 10px; flex:none; border:1px solid var(--hair); border-radius:7px;
    background:var(--surface); color:var(--fg2); font:inherit; font-size:12px; cursor:pointer;
  }
  .ds-lbtn:hover{ border-color:var(--hair-hi); color:var(--fg); }
  @media (max-width:860px){
    .ds-sbtn{ display:none; }
    .ds-top-in{ padding:0 14px; gap:10px; }
    .ds-logo .tag{ display:none; }
  }

  .ds-wrap{ max-width:1440px; margin:0 auto; display:flex; align-items:flex-start; }
  .ds-side{
    width:270px; flex:none; position:sticky; top:58px;
    height:calc(100vh - 58px); overflow-y:auto; padding:26px 14px 60px 22px;
    border-right:1px solid var(--hair);
  }
  .ds-side::-webkit-scrollbar{ width:8px; }
  .ds-side::-webkit-scrollbar-thumb{ background:var(--surface-3); border-radius:9px; }
  .ds-grp{ margin-bottom:20px; }
  .ds-grp > .h{
    font-family:'DM Mono',monospace; font-size:10px; letter-spacing:.13em; text-transform:uppercase;
    color:var(--fg3); padding:0 8px 7px;
  }
  .ds-side a{
    display:block; padding:6px 8px; border-radius:6px; text-decoration:none;
    font-size:13px; color:var(--fg2); line-height:1.45;
  }
  .ds-side a:hover{ background:var(--surface-2); color:var(--fg); }
  .ds-side a.on{ background:var(--accent-bg); color:var(--accent-ink); font-weight:500; }

  .ds-main{ flex:1; min-width:0; padding:34px 46px 120px; }
  .ds-article{ max-width:760px; }
  .ds-crumb{
    font-family:'DM Mono',monospace; font-size:11px; letter-spacing:.08em; text-transform:uppercase;
    color:var(--fg3); margin-bottom:14px;
  }
  .ds-article h1{
    font-size:clamp(1.7rem,3.4vw,2.15rem); font-weight:700; letter-spacing:-.028em;
    line-height:1.16; margin:0 0 14px;
  }
  .ds-lead{ font-size:15.5px; line-height:1.75; color:var(--fg2); margin:0 0 30px; }
  .ds-article h2{
    font-size:19px; font-weight:650; letter-spacing:-.018em; line-height:1.3;
    margin:40px 0 12px; padding-top:8px; scroll-margin-top:74px;
  }
  .ds-article h3{
    font-size:15px; font-weight:600; margin:26px 0 8px; scroll-margin-top:74px;
  }
  .ds-article p{ font-size:14.5px; line-height:1.78; color:var(--fg2); margin:0 0 14px; }
  .ds-article ul, .ds-article ol{ margin:0 0 16px; padding-left:22px; }
  .ds-article li{ font-size:14.5px; line-height:1.78; color:var(--fg2); margin-bottom:7px; }
  .ds-article a{ color:var(--accent-ink); text-decoration:none; border-bottom:1px solid var(--accent-line); }
  .ds-article a:hover{ border-bottom-color:var(--accent); }
  .ds-article strong{ color:var(--fg); font-weight:600; }
  .ds-article code{
    font-family:'DM Mono','JetBrains Mono',monospace; font-size:12.5px;
    background:var(--surface-2); border:1px solid var(--hair); border-radius:4px;
    padding:1.5px 5px; color:var(--fg);
  }
  .ds-article pre{
    margin:0 0 20px; padding:15px 17px; overflow-x:auto;
    background:var(--code-bg); border:1px solid var(--code-line); border-radius:8px;
  }
  .ds-article pre code{
    background:none; border:0; padding:0; font-size:12.5px; line-height:1.85;
    color:var(--code-fg); white-space:pre;
  }
  .ds-article table{
    width:100%; border-collapse:collapse; margin:0 0 20px; font-size:13.5px;
    /* 窄屏宽表格：390 下这张 366px 的「Verb / What it does / Typical call」
       表把正文撑宽 12px。display:block + overflow-x:auto 让表格在自己的盒子
       里横滚，tbody 仍按表格布局渲染，视觉上还是表，只是可以左右拖。 */
    display:block; overflow-x:auto; -webkit-overflow-scrolling:touch;
  }
  .ds-article th, .ds-article td{
    text-align:left; padding:9px 12px; border-bottom:1px solid var(--hair); vertical-align:top;
  }
  .ds-article th{
    font-family:'DM Mono',monospace; font-size:10.5px; letter-spacing:.1em;
    text-transform:uppercase; color:var(--fg3); font-weight:400;
  }
  .ds-article td{ color:var(--fg2); line-height:1.65; }
  .ds-callout{
    display:flex; gap:11px; padding:13px 15px; margin:0 0 20px;
    border:1px solid var(--accent-line); background:var(--accent-bg); border-radius:8px;
    font-size:13.5px; line-height:1.7; color:var(--fg2);
  }
  .ds-callout b{ color:var(--fg); font-weight:600; }
  .ds-callout svg{ width:15px; height:15px; flex:none; margin-top:2px; color:var(--accent-ink); }
  .ds-cards{ display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:12px; margin:0 0 22px; }
  .ds-card{
    display:block; padding:16px; border:1px solid var(--hair); border-radius:8px;
    background:var(--surface); text-decoration:none; border-bottom:1px solid var(--hair);
  }
  .ds-card:hover{ border-color:var(--hair-hi); }
  .ds-card .t{ display:block; font-size:13.5px; color:var(--fg); margin-bottom:5px; }
  .ds-card .d{ display:block; font-size:12px; line-height:1.6; color:var(--fg3); }
  .ds-nav2{ display:flex; gap:12px; margin-top:44px; padding-top:20px; border-top:1px solid var(--hair); }
  .ds-nav2 a{
    flex:1; padding:13px 15px; border:1px solid var(--hair); border-radius:8px;
    text-decoration:none; border-bottom:1px solid var(--hair);
  }
  .ds-nav2 a:hover{ border-color:var(--hair-hi); }
  .ds-nav2 .k{ display:block; font-size:11px; color:var(--fg3); margin-bottom:4px; }
  .ds-nav2 .v{ display:block; font-size:13.5px; color:var(--fg); }
  @media (max-width:900px){
    .ds-side{ display:none; }
    .ds-main{ padding:26px 18px 90px; }
  }

  .ds-toc{ width:210px; flex:none; position:sticky; top:58px; padding:34px 22px 60px 10px; }
  .ds-toc .h{
    font-family:'DM Mono',monospace; font-size:10px; letter-spacing:.13em; text-transform:uppercase;
    color:var(--fg3); margin-bottom:10px;
  }
  .ds-toc a{
    display:block; font-size:12.5px; line-height:1.5; color:var(--fg3);
    text-decoration:none; padding:3px 0;
  }
  .ds-toc a:hover{ color:var(--fg); }
  @media (max-width:1180px){ .ds-toc{ display:none; } }

  .ds-dlg{
    position:fixed; inset:0; z-index:120; display:none;
    background:rgba(5,5,10,.55); backdrop-filter:blur(3px);
    padding:80px 16px 16px; justify-content:center; align-items:flex-start;
  }
  .ds-dlg.on{ display:flex; }
  .ds-dlg-in{
    width:100%; max-width:560px; background:var(--surface); border:1px solid var(--hair-hi);
    border-radius:10px; overflow:hidden; box-shadow:var(--shadow);
  }
  .ds-dlg-in input{
    width:100%; height:48px; padding:0 16px; border:0; border-bottom:1px solid var(--hair);
    background:transparent; color:var(--fg); font:inherit; font-size:14.5px; outline:none;
  }
  .ds-dlg-list{ max-height:52vh; overflow-y:auto; padding:7px; }
  .ds-dlg-list a{
    display:block; padding:9px 11px; border-radius:6px; text-decoration:none; color:var(--fg2);
    font-size:13.5px;
  }
  .ds-dlg-list a:hover, .ds-dlg-list a.hot{ background:var(--surface-2); color:var(--fg); }
  .ds-dlg-list .g{
    font-family:'DM Mono',monospace; font-size:10px; letter-spacing:.12em; text-transform:uppercase;
    color:var(--fg3); padding:12px 11px 5px;
  }

  html[data-theme="dark"]{
    --brand-teal:#9B8DFF;
    --brand-slate:#A9A5BC;
    --brand-teal-bg:rgba(155,141,255,.14);
    --brand-teal-line:rgba(155,141,255,.34);
    --brand-slate-bg:rgba(169,165,188,.10);
    --brand-slate-line:rgba(169,165,188,.26);
    --tk-s:#B8C4DA; --tk-f:#F3F2FA; --tk-n:#CBB2FF;
  }
  html[data-theme="light"]{
    --brand-teal:#6D5BD0;
    --brand-slate:#7C7890;
    --brand-teal-bg:rgba(109,91,208,.09);
    --brand-teal-line:rgba(109,91,208,.28);
    --brand-slate-bg:rgba(124,120,144,.09);
    --brand-slate-line:rgba(124,120,144,.26);
    --code-bg:#FFFFFF;
    --code-bar:#F4F4F5;
    --code-line:rgba(9,9,11,.08);
    --code-fg:#18181B;
    --tk-k:#5B47B8; --tk-s:#3E4A63; --tk-c:#A1A1AA; --tk-p:#52525B;
    --tk-f:#020202; --tk-n:#6D5BD0;
  }
  .tk-f{ color:var(--tk-f); }
  .tk-n{ color:var(--tk-n); }
  html[data-theme="light"] .dots i{ background:#D4D4D8; }
  html[data-theme="light"] .tab:hover{ color:var(--fg2); background:rgba(9,9,11,.05); }
  html[data-theme="light"] .tab.on{ color:var(--fg); background:rgba(9,9,11,.07); }
  html[data-theme="light"] #copy-btn{ color:var(--fg3); }
  html[data-theme="light"] #copy-btn:hover{ color:var(--fg); background:rgba(9,9,11,.05); }
  html[data-theme="light"] .term-body::-webkit-scrollbar-thumb{ background:#D4D4D8; }
  html[data-theme="light"] .wire svg g[fill="#A1A1AA"] rect{ fill:var(--brand-slate); }

  /* ------------------------------------------- ornament from the logo ---- */
  .eyebrow::before{
    content:''; display:inline-block; width:5px; height:5px; border-radius:50%;
    background:var(--brand-teal); margin-right:8px; vertical-align:1px;
  }
  .step .num{ color:var(--brand-teal); }
  #stats > div{ position:relative; padding-top:15px; }
  #stats > div::before{
    content:''; position:absolute; left:0; top:0;
    width:24px; height:2px; border-radius:2px; background:var(--brand-slate);
  }
  #stats > div:first-child::before{ background:var(--brand-teal); }
  .layer:nth-child(1) .tagbox{ color:var(--brand-teal); border-color:var(--brand-teal-line); background:var(--brand-teal-bg); }
  .layer:nth-child(2) .tagbox{ color:var(--brand-slate); border-color:var(--brand-slate-line); background:var(--brand-slate-bg); }
  .layer:nth-child(3) .tagbox{ color:var(--accent-ink); border-color:var(--accent-line); background:var(--accent-bg); }
  .wire svg g[fill="#9B8DFF"] circle{ fill:var(--brand-teal); }
  .wire svg g[fill="#A1A1AA"] circle{ fill:var(--brand-slate); }
  .wire-legend i{ background:var(--brand-slate); }
  .wire-legend i.dash{ border-top-color:var(--brand-slate); }
  .wire-legend i.hot{ background:var(--brand-teal); }
  .intg .tp{ border-color:var(--brand-slate-line); color:var(--brand-slate); }
  /* 这里原本有一条 .logo .lg-os{ font-weight:700 }，把上面设的 900 降回 700，
     「OS 加粗」永远不生效。删掉，字重统一由 1225 行那条决定。 */
  #cta .card{
    background:linear-gradient(155deg, var(--brand-teal-bg) 0%, transparent 52%), var(--surface);
  }

  /* ------------------------------- the wireframe, repainted per skin ---- */
  html[data-theme="dark"]{
    --wire-fade:#FFFFFF; --wire-spine:#27272A; --wire-edge:#3F3F46;
    --wire-node:#0B0B0E; --wire-node-line:#52525B;
  }
  html[data-theme="light"]{
    --wire-fade:#09090B; --wire-spine:#D4D4D8; --wire-edge:#B4BCCB;
    --wire-node:#FFFFFF; --wire-node-line:#94A3B8;
  }
  .wire svg stop{ stop-color:var(--wire-fade); }
  .wire svg rect[stroke="rgba(255,255,255,0.05)"]{ stroke:var(--hair); }
  .wire svg line[stroke="#27272A"]{ stroke:var(--wire-spine); }
  .wire svg circle[stroke="#27272A"]{ stroke:var(--wire-spine); }
  .wire svg g[stroke="#3F3F46"]{ stroke:var(--wire-edge); }
  .wire svg circle[fill="#0B0B0E"]{ fill:var(--wire-node); }
  .wire svg circle[stroke="#52525B"]{ stroke:var(--wire-node-line); }

  /* Solid background for the sticky header and the mobile sheet.
     Plain rgba rather than color-mix() so older engines still paint correctly. */
  html[data-theme="dark"] #hdr.solid, html[data-theme="dark"] .sheet{ background:rgba(8,8,10,.86); }
  html[data-theme="light"] #hdr.solid, html[data-theme="light"] .sheet{ background:rgba(255,255,255,.88); }

  @media (prefers-reduced-motion: reduce){
    *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; }
    .reveal{ opacity:1; transform:none; }
  }
/* ===================================================================== *
 *  10 · DASHBOARD — the signed-in application shell                       *
 *                                                                         *
 *  mem0's dashboard is a dark app that ignores the marketing site's       *
 *  light/dark preference, so every colour here is fixed rather than       *
 *  token-driven. Metrics come from this server's own /api/dash/*, which   *
 *  in turn reads the live Mnemosyne OS gateway — nothing on these pages is   *
 *  invented placeholder data.                                             *
 * ===================================================================== */

body.dash{ background:#0D0C14; }
/* 控制台是全屏应用：营销站的公告条、页头、页脚、首页全部让位 */
body.dash #hdr, body.dash footer, body.dash #home, body.dash #announce{ display:none !important; }
body.dash #view{ display:block !important; }
/* 文档站是独立的版式：同样让营销站的框架让位 */
body.docs #hdr, body.docs footer, body.docs #home, body.docs #announce{ display:none !important; }
body.docs #view{ display:block !important; }

.dx{ --d-bg:#0D0C14; --d-panel:#131120; --d-panel2:#171528; --d-line:rgba(255,255,255,.075);
  --d-line2:rgba(255,255,255,.13); --d-fg:#F2F1F8; --d-fg2:#9C99B0; --d-fg3:#6E6B80;
  --d-accent:#CBB2FF; --d-accent2:#9B8DFF; --d-ok:#4ADE80; --d-warn:#FBBF24; --d-err:#F87171;
  min-height:100vh; background:var(--d-bg); color:var(--d-fg);
  font-family:'Inter Variable',Inter,system-ui,'PingFang SC','Microsoft YaHei',sans-serif;
  font-size:13.5px; display:flex; }
.dx *{ box-sizing:border-box; }
.dx a{ color:inherit; text-decoration:none; }
.dx ::-webkit-scrollbar{ width:9px; height:9px; }
.dx ::-webkit-scrollbar-track{ background:transparent; }
.dx ::-webkit-scrollbar-thumb{ background:#2A2740; border-radius:9px; }

/* ------------------------------------------------------------- sidebar */
.dx-side{ width:212px; flex:none; background:var(--d-panel); border-right:1px solid var(--d-line);
  display:flex; flex-direction:column; position:sticky; top:0; height:100vh; }
.dx-proj{ display:flex; align-items:center; gap:8px; padding:10px 12px; border-bottom:1px solid var(--d-line); flex:none; }
.dx-proj .av{ width:22px; height:22px; border-radius:5px; background:var(--d-accent); color:#171528;
  display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:600; flex:none; }
.dx-proj .nm{ font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dx-proj .sw{ margin-left:auto; font-size:10px; color:var(--d-fg3); flex:none; }
.dx-nav{ flex:1; overflow-y:auto; padding:10px 8px 14px; }
.dx-grp{ font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--d-fg3);
  padding:14px 8px 6px; }
.dx-it{ display:flex; align-items:center; gap:9px; padding:6px 8px; border-radius:6px;
  font-size:13px; color:var(--d-fg2); cursor:pointer; transition:background .15s, color .15s; }
.dx-it:hover{ background:rgba(255,255,255,.05); color:var(--d-fg); }
.dx-it.on{ background:rgba(255,255,255,.08); color:#fff; }
.dx-it svg{ width:14px; height:14px; flex:none; stroke-width:1.7; }
.dx-it .lb{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dx-it .bdg{ margin-left:auto; font-size:9.5px; padding:1px 5px; border-radius:4px;
  background:rgba(203,178,255,.16); color:var(--d-accent); flex:none; }
.dx-quota{ flex:none; padding:10px 12px; border-top:1px solid var(--d-line); }
.dx-quota .hd{ font-size:11.5px; color:var(--d-fg2); margin-bottom:8px; display:flex; align-items:center; gap:6px; }
.dx-quota .row{ display:flex; justify-content:space-between; font-size:11.5px; color:var(--d-fg3); margin-top:4px; }
.dx-quota .bar{ height:3px; border-radius:3px; background:rgba(255,255,255,.09); margin-top:4px; overflow:hidden; }
.dx-quota .bar i{ display:block; height:100%; background:var(--d-accent); }
.dx-links{ flex:none; border-top:1px solid var(--d-line); padding:8px 10px; display:flex; gap:2px; }
.dx-links a{ flex:1; text-align:center; font-size:11px; color:var(--d-fg3); padding:5px 0; border-radius:5px; }
.dx-links a:hover{ color:var(--d-fg); background:rgba(255,255,255,.05); }

/* ----------------------------------------------------------------- main */
.dx-main{ flex:1; min-width:0; display:flex; flex-direction:column; }
.dx-top{ display:flex; align-items:center; gap:12px; padding:9px 18px; border-bottom:1px solid var(--d-line);
  position:sticky; top:0; background:rgba(13,12,20,.92); backdrop-filter:blur(8px); z-index:6; flex:none; }
.dx-top .sp{ flex:1; }
.dx-up{ display:inline-flex; align-items:center; gap:6px; height:30px; padding:0 12px; border-radius:6px;
  background:var(--d-accent); color:#171528; font-size:12.5px; font-weight:500; cursor:pointer; border:0; }
.dx-up:hover{ background:#D8C4FF; }
.dx-ava{ width:28px; height:28px; border-radius:50%; background:var(--d-panel2); border:1px solid var(--d-line2);
  display:flex; align-items:center; justify-content:center; font-size:11.5px; cursor:pointer; color:var(--d-fg); }
.dx-cop{ display:flex; align-items:flex-start; gap:12px; margin:14px 18px 0; padding:11px 14px;
  border:1px solid var(--d-line); border-radius:8px; background:var(--d-panel); }
.dx-cop .ic{ width:22px; height:22px; border-radius:6px; background:rgba(203,178,255,.14); color:var(--d-accent);
  display:flex; align-items:center; justify-content:center; flex:none; }
.dx-cop .tx{ flex:1; min-width:0; }
.dx-cop .t1{ font-size:12.5px; color:var(--d-fg); }
.dx-cop .t2{ font-size:11.5px; color:var(--d-fg3); line-height:1.65; margin-top:3px; }
.dx-cop .go{ flex:none; height:28px; padding:0 11px; border-radius:6px; background:#fff; color:#171528;
  font-size:12px; font-weight:500; border:0; cursor:pointer; }
.dx-cop .xx{ flex:none; background:none; border:0; color:var(--d-fg3); cursor:pointer; font-size:15px; line-height:1; padding:2px 4px; }
.dx-cop .xx:hover{ color:var(--d-fg); }
.dx-body{ padding:18px; flex:1; min-width:0; }
.dx-h1{ font-size:19px; font-weight:500; margin:0; letter-spacing:-.01em; }
.dx-sub{ font-size:12.5px; color:var(--d-fg3); margin-top:5px; line-height:1.6; }
.dx-hrow{ display:flex; align-items:flex-start; gap:12px; margin-bottom:16px; }
.dx-hrow .sp{ flex:1; }
.dx-btn{ display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 13px; border-radius:6px;
  background:#fff; color:#171528; font-size:12.5px; font-weight:500; border:0; cursor:pointer; white-space:nowrap; }
.dx-btn:hover{ background:#EDEAF7; }
.dx-btn.gh{ background:transparent; color:var(--d-fg); border:1px solid var(--d-line2); }
.dx-btn.gh:hover{ background:rgba(255,255,255,.06); }
.dx-btn.dg{ background:var(--d-err); color:#2A0B0B; }
.dx-btn:disabled{ opacity:.45; cursor:not-allowed; }
.dx-btn.sm{ height:28px; padding:0 10px; font-size:12px; }

/* --------------------------------------------------------------- cards */
/* min-width:0 + 子项 min-width:0：grid item 默认 min-width:auto，
   列里的英文长句（"Unlimited end users"、"1,000 retrieval requests / month"）
   会按最大内容撑宽列 —— 即使已经是单列，整个 dx-grid 照样溢出容器。
   与首页 #res-grid 是同一个病。 */
.dx-grid{ display:grid; gap:12px; min-width:0; }
/* 兜底断行：英文长串（包名、URL、"Unlimited end users"、"1,000 retrieval
   requests / month"）在 390 的单列里仍会溢出。逐个页面加规则治不住 ——
   每加一段文案就复发一次，所以在 dx-body 顶层一次给齐。
   anywhere 与 break-all 的区别：它只在行真的放不下时才断，正常单词不被拆开。 */
.dx-body{ overflow-wrap:anywhere; }
/* 中间容器也要 min-width:0：dx-chips / dx-field 本身已经是 flex-wrap 或
   单列，但它们作为 flex/grid item 默认 min-width:auto，会被里面最长的
   一个 chip / 一行英文撑宽，于是 wrap 无从发生。 */
/* input 自带约 20 字符的默认 size，min-width:auto 下会把窄列撑破 58px */
.dx-body input.inp{ min-width:0; width:100%; }
.dx-body .dx-chips, .dx-body .dx-field, .dx-body .dx-f, .dx-body .f,
.dx-body .dx-plan, .dx-body .dx-card, .dx-body .dx-kpi{ min-width:0; }

.dx-k4{ grid-template-columns:repeat(4,minmax(0,1fr)); }
.dx-k2{ grid-template-columns:repeat(2,minmax(0,1fr)); }
.dx-g3{ grid-template-columns:repeat(3,minmax(0,1fr)); }
/* KPI/表单栅格此前是固定 3/4 列，没有任何窄屏降级 —— 390 下 4 列每列只剩
   82px，输入框与 KPI 直接把 dx-grid 撑破，实测 install 溢 41–54px、
   billing 溢 37–160px。按容器宽度逐级收列。 */
@media (max-width:1080px){ .dx-k4{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:640px){ .dx-g3{ grid-template-columns:1fr; } }
@media (max-width:520px){ .dx-k4, .dx-k3{ grid-template-columns:1fr; } }
@media (max-width:1100px){ .dx-k4{ grid-template-columns:repeat(2,1fr); } .dx-k2,.dx-g3{ grid-template-columns:1fr; } }
.dx-card{ border:1px solid var(--d-line); border-radius:8px; background:var(--d-panel); padding:15px 16px; }
.dx-card.pad0{ padding:0; }
.dx-kpi .lb{ display:flex; align-items:center; gap:6px; font-size:12px; color:var(--d-fg2); }
.dx-kpi .lb svg{ width:13px; height:13px; stroke-width:1.7; }
.dx-kpi .vl{ font-size:26px; font-weight:500; margin-top:10px; letter-spacing:-.02em; }
.dx-kpi .vl.na{ color:var(--d-fg3); }
.dx-kpi .ft{ font-size:11.5px; color:var(--d-fg3); margin-top:8px; }
.dx-chd{ display:flex; align-items:center; gap:8px; margin-bottom:14px; }
.dx-chd h3{ font-size:13.5px; font-weight:500; margin:0; }
.dx-chd .sp{ flex:1; }
.dx-chd .mo{ font-size:11.5px; color:var(--d-fg3); }
.dx-bars{ display:flex; flex-direction:column; gap:11px; }
.dx-bar .rw{ display:flex; justify-content:space-between; font-size:12.5px; margin-bottom:5px; }
.dx-bar .rw b{ font-weight:400; color:var(--d-fg2); }
.dx-bar .tk{ height:6px; border-radius:3px; background:rgba(255,255,255,.07); overflow:hidden; }
.dx-bar .tk i{ display:block; height:100%; border-radius:3px; background:var(--d-accent2); }
.dx-empty{ text-align:center; padding:46px 20px 52px; }
.dx-empty .ic{ width:66px; height:44px; margin:0 auto 16px; border-radius:7px; border:1px solid var(--d-line2);
  background:linear-gradient(160deg,#1B1830,#151325); position:relative; }
.dx-empty .ic::after{ content:''; position:absolute; right:-5px; top:-5px; width:15px; height:15px; border-radius:50%;
  background:var(--d-panel2); border:1px solid var(--d-line2); }
.dx-empty h3{ font-size:13.5px; font-weight:500; margin:0 0 7px; }
.dx-empty p{ font-size:12.5px; color:var(--d-fg3); margin:0 auto; max-width:400px; line-height:1.7; }
.dx-empty .go{ margin-top:16px; }

/* --------------------------------------------------------------- table */
.dx-tools{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
.dx-inp{ height:32px; padding:0 11px; border-radius:6px; border:1px solid var(--d-line2);
  background:var(--d-panel2); color:var(--d-fg); font:inherit; font-size:12.5px; min-width:0; }
.dx-inp:focus{ outline:none; border-color:var(--d-accent2); }
.dx-inp.wide{ flex:1; min-width:180px; }
.dx-sel{ height:32px; padding:0 9px; border-radius:6px; border:1px solid var(--d-line2);
  background:var(--d-panel2); color:var(--d-fg2); font:inherit; font-size:12.5px; }
.dx-tabs{ display:inline-flex; gap:2px; padding:3px; background:var(--d-panel2); border-radius:7px; }
.dx-tabs button{ height:26px; padding:0 11px; border-radius:5px; border:0; background:transparent;
  color:var(--d-fg2); font:inherit; font-size:12.5px; cursor:pointer; }
.dx-tabs button.on{ background:rgba(255,255,255,.13); color:#fff; }
.dx-tbl{ width:100%; border-collapse:collapse; font-size:12.5px; }
.dx-tbl th, .dx-tbl td{ text-align:left; padding:11px 14px; border-bottom:1px solid var(--d-line); vertical-align:middle; }
.dx-tbl thead th{ font-size:11.5px; font-weight:400; color:var(--d-fg3); background:rgba(255,255,255,.02); }
.dx-tbl tbody tr:hover{ background:rgba(255,255,255,.028); }
.dx-tbl .mono{ font-family:'DM Mono',monospace; font-size:11.5px; color:var(--d-fg2); }
.dx-tbl .ell{ max-width:520px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dx-tag{ display:inline-block; font-size:10.5px; padding:2px 7px; border-radius:4px;
  background:rgba(255,255,255,.07); color:var(--d-fg2); margin-right:4px; }
.dx-tag.p{ background:rgba(203,178,255,.16); color:var(--d-accent); }
.dx-tag.g{ background:rgba(74,222,128,.14); color:var(--d-ok); }
.dx-pager{ display:flex; align-items:center; gap:10px; padding:12px 14px; font-size:12px; color:var(--d-fg3); }
.dx-pager .sp{ flex:1; }
.dx-pager button{ height:26px; padding:0 10px; border-radius:5px; border:1px solid var(--d-line2);
  background:transparent; color:var(--d-fg2); font:inherit; font-size:12px; cursor:pointer; }
.dx-pager button:hover:not(:disabled){ color:#fff; border-color:var(--d-fg3); }

/* ------------------------------------------------------------ install */
.dx-steps{ display:grid; grid-template-columns:repeat(4,1fr); gap:0; margin:24px 0 8px; }
@media (max-width:900px){ .dx-steps{ grid-template-columns:repeat(2,1fr); } }

/* ------------------------------------------------ 控制台：≤820px 收成单列 */
/* 控制台是 flex 双栏：侧栏固定 212px + 主区 flex:1。390 视口下主区只剩 178px，
   而 .dx-top 里「语言切换 + 升级 + 头像」固定宽加起来 214px，整页被撑出
   37–53px（中英都中）。国际惯例的做法是窄屏把侧栏收成顶部横向 tab 条 ——
   导航一个不少，但不再和主区抢宽度，主区拿到整屏。 */
@media (max-width:820px){
  .dx{ display:block; }
  .dx-side{
    width:auto; height:auto; position:static; flex-direction:row; align-items:center;
    border-right:0; border-bottom:1px solid var(--d-line);
    overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch;
  }
  .dx-proj{ flex:none; border-bottom:0; border-right:1px solid var(--d-line); }
  .dx-nav{ display:flex; flex:1 1 auto; min-width:0; gap:2px; padding:6px 8px; overflow:visible; }
  .dx-grp{ display:none; }            /* 分组标题在横排里只会制造断点 */
  .dx-it{ flex:none; white-space:nowrap; padding:6px 10px; }
  .dx-it .bdg{ margin-left:6px; }
  .dx-quota, .dx-links{ display:none; }  /* 配额与外部链接在手机上另有入口 */
  .dx-top{ flex-wrap:wrap; row-gap:8px; padding:8px 12px; }
  .dx-top .sp{ display:none; }
}
.dx-step{ padding:0 10px; text-align:center; position:relative; }
.dx-step .ic{ width:34px; height:34px; margin:0 auto 9px; border-radius:7px; border:1px solid var(--d-line2);
  display:flex; align-items:center; justify-content:center; color:var(--d-fg2); background:var(--d-panel2); }
.dx-step .ic svg{ width:15px; height:15px; stroke-width:1.7; }
.dx-step.on .ic{ background:var(--d-accent); color:#171528; border-color:transparent; }
.dx-step .t{ font-size:12.5px; }
.dx-step .s{ font-size:11px; color:var(--d-fg3); margin-top:4px; }
.dx-pane{ margin-top:22px; }
.dx-blk{ margin-bottom:22px; }
.dx-blk > .h{ font-size:12.5px; margin-bottom:8px; color:var(--d-fg); }
.dx-blk > .d{ font-size:11.5px; color:var(--d-fg3); margin-bottom:10px; line-height:1.65; }
.dx-code{ position:relative; border:1px solid var(--d-line); border-radius:7px; background:#0A0917; padding:11px 13px;
  font-family:'DM Mono',monospace; font-size:12px; color:#DED9F5; overflow-x:auto; white-space:pre; }
.dx-code .cp{ position:absolute; right:7px; top:7px; height:24px; padding:0 8px; border-radius:5px;
  border:1px solid var(--d-line2); background:var(--d-panel2); color:var(--d-fg2); font-size:11px; cursor:pointer; }
.dx-code .cp:hover{ color:#fff; }
.dx-keys{ display:flex; flex-direction:column; gap:8px; }
.dx-key{ display:flex; align-items:center; gap:10px; padding:11px 13px; border:1px solid var(--d-line);
  border-radius:7px; background:var(--d-panel); }
.dx-key .nm{ font-size:12.5px; }
.dx-key .mono{ font-family:'DM Mono',monospace; font-size:11.5px; color:var(--d-fg2); }
.dx-key .sp{ flex:1; }
.dx-note{ display:flex; gap:9px; padding:11px 13px; border-radius:7px; font-size:12px; line-height:1.65;
  background:rgba(203,178,255,.08); border:1px solid rgba(203,178,255,.22); color:#DCD3FA; margin-bottom:14px; }
.dx-field{ margin-bottom:14px; }
.dx-field label{ display:block; font-size:12px; color:var(--d-fg2); margin-bottom:6px; }
.dx-field .inp{ width:100%; height:34px; padding:0 11px; border-radius:6px; border:1px solid var(--d-line2);
  background:var(--d-panel2); color:var(--d-fg); font:inherit; font-size:12.5px; }
.dx-field .inp:focus{ outline:none; border-color:var(--d-accent2); }
.dx-field textarea.inp{ height:auto; min-height:96px; padding:9px 11px; resize:vertical; line-height:1.65; }
.dx-field .hint{ font-size:11px; color:var(--d-fg3); margin-top:5px; }
.dx-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.dx-chip{ padding:6px 13px; border-radius:6px; border:1px solid var(--d-line2); background:var(--d-panel2);
  color:var(--d-fg2); font-size:12.5px; cursor:pointer; }
.dx-chip:hover{ color:#fff; }
.dx-chip.on{ background:var(--d-accent); color:#171528; border-color:transparent; }
.dx-dz{ border:1px solid rgba(248,113,113,.3); border-radius:8px; padding:14px 16px; background:rgba(248,113,113,.05); }
.dx-dz h4{ font-size:12.5px; margin:0 0 4px; color:var(--d-err); }
.dx-dz p{ font-size:11.5px; color:var(--d-fg3); margin:0 0 11px; line-height:1.6; }
.dx-dz .rw{ display:flex; align-items:center; gap:12px; padding:9px 0; border-top:1px solid rgba(248,113,113,.16); }
.dx-dz .rw .sp{ flex:1; }
.dx-dz .rw .t{ font-size:12px; }
.dx-dz .rw .s{ font-size:11px; color:var(--d-fg3); margin-top:2px; }
.dx-plan{ border:1px solid var(--d-line); border-radius:8px; padding:16px; background:var(--d-panel); display:flex; flex-direction:column; }
.dx-plan.cur{ border-color:var(--d-accent2); }
.dx-plan .nm{ font-size:13px; font-weight:500; }
.dx-plan .pr{ font-size:19px; margin:10px 0 4px; }
.dx-plan .pr span{ font-size:12px; color:var(--d-fg3); }
.dx-plan ul{ list-style:none; margin:12px 0 16px; padding:0; display:flex; flex-direction:column; gap:7px; }
.dx-plan li{ font-size:12px; color:var(--d-fg2); display:flex; gap:7px; align-items:flex-start; }
.dx-plan li::before{ content:''; width:11px; height:11px; flex:none; margin-top:3px; border-radius:50%;
  background:rgba(203,178,255,.2); }
.dx-plan .f{ margin-top:auto; }
.dx-plan .cur-tag{ font-size:10.5px; padding:2px 7px; border-radius:4px; background:rgba(203,178,255,.16); color:var(--d-accent); }

/* ----------------------------------------------------------- copilot */
.dx-chat{ max-width:720px; margin:34px auto 0; }
.dx-chat h2{ font-size:15px; font-weight:500; text-align:center; margin:0 0 8px; }
.dx-chat .sub{ font-size:12px; color:var(--d-fg3); text-align:center; line-height:1.7; margin-bottom:20px; }
.dx-ask{ display:flex; align-items:center; gap:9px; padding:9px 12px; border:1px solid var(--d-line2);
  border-radius:9px; background:var(--d-panel2); }
.dx-ask input{ flex:1; background:none; border:0; color:var(--d-fg); font:inherit; font-size:13px; }
.dx-ask input:focus{ outline:none; }
.dx-ask .sd{ width:26px; height:26px; border-radius:50%; background:var(--d-accent2); color:#fff; border:0;
  cursor:pointer; display:flex; align-items:center; justify-content:center; flex:none; }
.dx-sug{ display:flex; flex-direction:column; gap:2px; margin-top:18px; }
.dx-sug button{ display:flex; align-items:center; gap:9px; padding:9px 10px; border:0; border-radius:6px;
  background:transparent; color:var(--d-fg2); font:inherit; font-size:12.5px; text-align:left; cursor:pointer; }
.dx-sug button:hover{ background:rgba(255,255,255,.05); color:var(--d-fg); }
.dx-sug svg{ width:14px; height:14px; flex:none; stroke-width:1.7; }
.dx-msg{ margin-top:18px; display:flex; flex-direction:column; gap:12px; }
.dx-msg .m{ border:1px solid var(--d-line); border-radius:8px; padding:13px 15px; font-size:12.5px; line-height:1.75; }
.dx-msg .m.me{ background:var(--d-panel2); }
.dx-msg .m .who{ font-size:11px; color:var(--d-fg3); margin-bottom:7px; }
.dx-msg .m pre{ margin:8px 0 0; font-family:'DM Mono',monospace; font-size:11.5px; color:#DED9F5;
  white-space:pre-wrap; word-break:break-word; }

/* -------------------------------------------------------------- graph */
.dx-gwrap{ border:1px solid var(--d-line); border-radius:8px; background:var(--d-panel); overflow:hidden; position:relative; }
.dx-gwrap svg{ display:block; width:100%; height:520px; }
.dx-legend{ display:flex; gap:14px; flex-wrap:wrap; padding:11px 14px; border-top:1px solid var(--d-line);
  font-size:11.5px; color:var(--d-fg3); }
.dx-legend i{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:5px; }

/* ------------------------------------------------------- docs layout */
.dx-docs{ display:flex; gap:0; }
.dx-dnav{ width:236px; flex:none; padding:22px 16px 60px; border-right:1px solid var(--d-line);
  position:sticky; top:0; height:100vh; overflow-y:auto; }
.dx-dnav .grp{ font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--d-fg3); margin:18px 0 7px; }
.dx-dnav a{ display:block; padding:5px 8px; border-radius:5px; font-size:12.5px; color:var(--d-fg2); }
.dx-dnav a:hover{ background:rgba(255,255,255,.05); color:var(--d-fg); }
.dx-dnav a.on{ background:rgba(203,178,255,.14); color:var(--d-accent); }
.dx-doc{ flex:1; min-width:0; padding:30px 40px 80px; max-width:820px; }
.dx-doc h1{ font-size:26px; font-weight:500; margin:0 0 14px; letter-spacing:-.02em; }
.dx-doc h2{ font-size:17px; font-weight:500; margin:30px 0 10px; }
.dx-doc h3{ font-size:14px; font-weight:500; margin:22px 0 8px; }
.dx-doc p, .dx-doc li{ font-size:13.5px; line-height:1.85; color:#CFCBE4; }
.dx-doc ul{ padding-left:20px; }
.dx-doc code{ font-family:'DM Mono',monospace; font-size:12px; background:rgba(255,255,255,.07);
  padding:1px 5px; border-radius:4px; }
.dx-doc table{ width:100%; border-collapse:collapse; margin:14px 0; font-size:12.5px; }
.dx-doc th, .dx-doc td{ text-align:left; padding:9px 12px; border-bottom:1px solid var(--d-line); }
.dx-doc th{ color:var(--d-fg3); font-weight:400; }
.dx-dsep{ height:1px; background:var(--d-line); margin:26px 0; }
/* 后台管理里的「站点配置」。这批组件原本各自是控制台的一整页，而 .dx 是
   display:flex + min-height:100vh（为「侧栏 + 主体」而写）。直接拼接会让
   四个块被横着排、还撑出一屏空白 —— 这就是错行的来源。这里只关掉整页行为，
   改成竖直堆叠的卡片，并让网格按可用宽度自适应换行。 */
.site-cfg{
  /* 这一页是长表单，深色面板读起来很累，而且一旦背景透明就会变成
     「白底 + 深色主题的近白文字」—— 实测对比度接近 0，整页看不见字。
     所以整套变量在这里就地换成浅色主题：深字、浅框、浅描边。
     只作用于 .site-cfg 子树，不影响控制台其它页面。 */
  display:block; min-height:auto;
  --d-panel:#FFFFFF; --d-panel2:#F6F5FA;
  --d-line:rgba(16,16,24,.10); --d-line2:rgba(16,16,24,.18);
  --d-fg:#17151F; --d-fg2:#4A4757; --d-fg3:#75717F;
  --d-accent:#6D4AE0; --d-accent2:#5B3FD6;
  background:#FBFBFD; color:var(--d-fg);
  border-radius:12px;
}
.site-cfg .site-sec{ background:transparent; border:1px solid var(--d-line);
  border-radius:12px; padding:18px 20px; margin-bottom:14px; }
.site-cfg .dx-hrow{ margin-bottom:14px; }
.site-cfg .dx-hrow .dx-h1{ font-size:16px; font-weight:600; }
/* 深色主题里这两处是「浅紫字 + 淡紫底」和「无边框纯白按钮」——
   搬到浅底上，前者读不清、后者看不出轮廓。只在本页子树内改。 */
.site-cfg .dx-note{
  background:#F4F1FE; border-color:rgba(109,74,224,.22); color:#463A66;
}
.site-cfg .dx-btn{ border:1px solid var(--d-line2); }
.site-cfg .dx-btn.gh{ background:#fff; }
.site-cfg .dx-btn:hover{ background:#EDEAF7; }
/* 一条规则覆盖 dx-grid / dx-k2 / dx-g3 / dx-k4 的所有变体：
   特异性比单个 .dx-xx 高，窄容器里会自动落到单列，不再挤压错行。 */
.site-cfg .dx-grid{ grid-template-columns:repeat(auto-fit, minmax(220px, 1fr)); }
.dx-search{ display:flex; align-items:center; gap:8px; flex:1; max-width:420px; height:32px; padding:0 11px;
  border:1px solid var(--d-line2); border-radius:7px; background:var(--d-panel2); color:var(--d-fg3); }
.dx-search input{ flex:1; background:none; border:0; color:var(--d-fg); font:inherit; font-size:12.5px; }
.dx-search input:focus{ outline:none; }
.dx-search kbd{ font-family:inherit; font-size:10.5px; border:1px solid var(--d-line2); border-radius:4px; padding:1px 5px; }
