<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>项目学习 on GoClub</title><link>https://go.botsarena.tech/docs/project-study/</link><description>Recent content in 项目学习 on GoClub</description><generator>Hugo</generator><language>zh-cn</language><atom:link href="https://go.botsarena.tech/docs/project-study/index.xml" rel="self" type="application/rss+xml"/><item><title>GCFeed 面试问题与答案清单</title><link>https://go.botsarena.tech/docs/project-study/gcfeed-interview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://go.botsarena.tech/docs/project-study/gcfeed-interview/</guid><description>&lt;h1 id="gcfeed-面试问题与答案清单"&gt;
 &lt;a class="page-home-link" href="https://go.botsarena.tech/"&gt;GCFeed 面试问题与答案清单&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;这份清单用于围绕 GCFeed 做项目面试复盘。每个问题下面给出一版可直接作答的参考答案，建议回答时按“项目现状、设计原因、扩展方向”三段展开。&lt;/p&gt;

&lt;h2 id="1-项目总览"&gt;1. 项目总览&lt;a class="anchor" href="#1-%e9%a1%b9%e7%9b%ae%e6%80%bb%e8%a7%88"&gt;#&lt;/a&gt;&lt;/h2&gt;


&lt;h3 id="基础问题"&gt;基础问题&lt;a class="anchor" href="#%e5%9f%ba%e7%a1%80%e9%97%ae%e9%a2%98"&gt;#&lt;/a&gt;&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;GCFeed 解决的核心业务问题是什么？&lt;/p&gt;
&lt;p&gt;答：GCFeed 是一个短视频 Feed 系统，覆盖内容发布、Feed 分发、刷流消费、互动计数、曝光反馈、推荐排序、消息通知和播放优化。它的核心目标是让用户能稳定、低延迟地刷到视频内容，同时让发布、互动和推荐这些高频链路具备扩展能力。项目重点展示后端系统设计能力，包括缓存、异步解耦、游标分页、推拉结合关注流和监控压测。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;这个项目的后端、前端、数据库、缓存和消息队列分别用了什么技术？&lt;/p&gt;
&lt;p&gt;答：后端使用 Go、Gin 和 GORM，前端使用 React 和 Vite，数据库使用 MySQL，缓存使用 Redis，消息队列使用 RabbitMQ。鉴权使用 JWT，监控使用 Prometheus 和 Grafana，本地编排使用 Docker Compose。代码按 &lt;code&gt;Domain / Application / Infrastructure / Interfaces&lt;/code&gt; 四层组织，适合讲清业务边界和技术实现边界。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从用户发布视频到另一个用户刷到视频，完整链路有哪些步骤？&lt;/p&gt;
&lt;p&gt;答：用户先上传媒体文件，拿到视频和封面 URL，再调用 &lt;code&gt;POST /api/videos&lt;/code&gt; 创建公开视频，视频和统计数据写入 MySQL。发布成功后会投递视频发布事件，Worker 进行 Feed 预热、关注流 fanout 或 Author Outbox 写入。其他用户请求 &lt;code&gt;/api/feed-items&lt;/code&gt; 时，Feed Service 根据 scene 读取轻量页，再批量组装视频卡片、作者信息和计数，最后返回游标分页结果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;项目里有哪些 Feed 场景？&lt;code&gt;timeline&lt;/code&gt;、&lt;code&gt;hot&lt;/code&gt;、&lt;code&gt;following&lt;/code&gt;、&lt;code&gt;recommend&lt;/code&gt; 的差异是什么？&lt;/p&gt;
&lt;p&gt;答：&lt;code&gt;timeline&lt;/code&gt; 按发布时间倒序读取公开视频，适合最新流；&lt;code&gt;hot&lt;/code&gt; 基于 Redis 分钟桶热度分读取一小时滑动热榜；&lt;code&gt;following&lt;/code&gt; 合并用户 inbox 和关注作者 outbox，提供关注流；&lt;code&gt;recommend&lt;/code&gt; 调用推荐服务生成候选，再复用 Feed 卡片组装链路。代码里通过 &lt;code&gt;Strategy&lt;/code&gt; 接口和 scene 策略注册表统一管理这些场景。&lt;/p&gt;</description></item><item><title>Nakamoto共识（Go语言）学习</title><link>https://go.botsarena.tech/docs/project-study/study-blockchain/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://go.botsarena.tech/docs/project-study/study-blockchain/</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN" data-theme="light"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;link rel="icon" href="https://go.botsarena.tech/favicon.png"&gt;
&lt;title&gt;Nakamoto共识（Go语言）学习&lt;/title&gt;
&lt;style&gt;
:root{
 --bg:#fbf8ef;--bg2:#f2ead8;--bg3:#e4d6b8;--fg:#201a12;--fg2:#786a55;--fg3:#a99574;
 --card:#fffaf0;--border:#e8dcc4;--accent:#b7791f;--accent2:#7c3f09;--accent-soft:#fff4d6;--accent-glow:rgba(183,121,31,.18);
 --green:#1f9d72;--green-soft:#eaf8ef;--blue:#2563eb;--blue-soft:#eaf1ff;--warn:#d97706;--warn-soft:#fff7e8;--danger:#dc2626;--danger-soft:#fff1f1;
 --code-bg:#fff7e6;--code-border:#ead9b5;--shadow-sm:0 1px 2px rgba(72,43,10,.06);--shadow-md:0 18px 48px rgba(72,43,10,.12);
 --sidebar-w:292px;--topnav-h:58px;--radius:16px;--radius-sm:10px;
 --font-body:'Noto Sans SC','PingFang SC','Microsoft YaHei',sans-serif;--font-mono:'JetBrains Mono','Fira Code',Consolas,monospace;
 --lv1:#1f9d72;--lv1-soft:#eaf8ef;--lv2:#2563eb;--lv2-soft:#eaf1ff;--lv3:#d97706;--lv3-soft:#fff7e8;
 --noise:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
}
[data-theme="dark"]{
 --bg:#101010;--bg2:#181510;--bg3:#282116;--fg:#fff8ea;--fg2:#c8b99c;--fg3:#917f5c;
 --card:#19150f;--border:#2d2417;--accent:#f3b13f;--accent2:#d97706;--accent-soft:#31200a;--accent-glow:rgba(243,177,63,.14);
 --green-soft:#062b20;--blue-soft:#0c1a38;--warn-soft:#2f1c04;--danger-soft:#320b0b;--code-bg:#20170a;--code-border:#36250e;--shadow-sm:0 1px 2px rgba(0,0,0,.4);--shadow-md:0 20px 60px rgba(0,0,0,.42);
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased}
body{min-height:100vh;background:
 radial-gradient(circle at 14% 8%,rgba(243,177,63,.20),transparent 28%),
 radial-gradient(circle at 86% 14%,rgba(37,99,235,.13),transparent 30%),
 linear-gradient(180deg,var(--bg),#fffdf7 52%,var(--bg));
 color:var(--fg);font-family:var(--font-body);font-size:15px;line-height:1.7;transition:background .25s,color .25s}
[data-theme="dark"] body{background:
 radial-gradient(circle at 16% 8%,rgba(243,177,63,.16),transparent 30%),
 radial-gradient(circle at 86% 14%,rgba(37,99,235,.12),transparent 34%),
 linear-gradient(180deg,#0b0b0b,#11100d 52%,#080807)}
body::before{content:'';position:fixed;inset:0;background:var(--noise);pointer-events:none;z-index:9999;opacity:.48;mix-blend-mode:multiply}
[data-theme="dark"] body::before{opacity:.16;mix-blend-mode:screen}
a{color:var(--accent);text-decoration:none}
button{border:0;background:none;color:inherit;font:inherit;cursor:pointer}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-thumb{background:var(--fg3);border-radius:10px}
.topnav{height:var(--topnav-h);display:flex;align-items:center;gap:10px;padding:0 20px;background:rgba(255,250,240,.82);border-bottom:1px solid rgba(255,255,255,.78);box-shadow:0 18px 55px rgba(72,43,10,.10);backdrop-filter:blur(24px) saturate(1.25);position:sticky;top:0;z-index:100}
[data-theme="dark"] .topnav{background:rgba(18,15,10,.78);border-color:rgba(255,255,255,.09);box-shadow:0 18px 55px rgba(0,0,0,.38)}
.brand{display:flex;align-items:center;gap:10px;margin-right:auto;white-space:nowrap}
.brand-icon{width:34px;height:34px;border-radius:12px;background:linear-gradient(145deg,#ffe8a3,#f3b13f);display:grid;place-items:center;box-shadow:0 8px 20px var(--accent-glow);overflow:hidden}
.brand-icon svg{width:30px;height:30px}
.brand-text{font-size:15px;font-weight:900}.brand-sub{font-size:11px;color:var(--fg3);margin-left:4px}
.mode-tabs{display:flex;background:rgba(255,255,255,.44);border:1px solid rgba(255,255,255,.70);border-radius:12px;padding:4px;gap:2px;box-shadow:0 1px 0 rgba(255,255,255,.75) inset}
[data-theme="dark"] .mode-tabs{background:rgba(255,255,255,.055);border-color:rgba(255,255,255,.10)}
.mode-btn{padding:6px 13px;border-radius:9px;font-size:13px;font-weight:850;color:var(--fg2);transition:all .18s}
.mode-btn:hover{background:var(--accent-soft);color:var(--accent)}
.mode-btn.active{background:linear-gradient(180deg,#2f2515,#14100a);color:#fff;box-shadow:0 12px 28px rgba(32,26,18,.22),0 1px 0 rgba(255,255,255,.22) inset}
[data-theme="dark"] .mode-btn.active{background:linear-gradient(180deg,rgba(255,255,255,.18),rgba(255,255,255,.08))}
.repo-link,.theme-btn,.search-box{background:rgba(255,255,255,.48);border:1px solid rgba(255,255,255,.76);box-shadow:0 1px 0 rgba(255,255,255,.62) inset,0 10px 24px rgba(72,43,10,.06);backdrop-filter:blur(18px)}
[data-theme="dark"] .repo-link,[data-theme="dark"] .theme-btn,[data-theme="dark"] .search-box{background:rgba(255,255,255,.065);border-color:rgba(255,255,255,.10);box-shadow:0 1px 0 rgba(255,255,255,.08) inset,0 12px 30px rgba(0,0,0,.22)}
.repo-link{display:flex;align-items:center;gap:6px;padding:7px 12px;border-radius:10px;color:var(--fg2);font-size:13px;font-weight:800;line-height:1;white-space:nowrap;transition:all .2s}
.repo-link:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.search-wrap{position:relative}.search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--fg3);pointer-events:none}
.search-box{width:210px;padding:7px 12px 7px 32px;border-radius:10px;color:var(--fg);font-size:13px;outline:none;transition:all .2s}
.search-box:focus{width:280px;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.theme-btn{width:34px;height:34px;border-radius:10px;color:var(--fg2);display:grid;place-items:center;font-size:16px}.theme-btn:hover{color:var(--accent)}
.progress-pill{display:flex;align-items:center;gap:6px;padding:5px 12px;border-radius:20px;background:var(--green-soft);border:1px solid rgba(31,157,114,.25);font-size:12px;font-weight:900;color:var(--green)}
.dot{width:7px;height:7px;border-radius:50%;background:var(--green)}
.app{display:flex;height:calc(100vh - var(--topnav-h));overflow:hidden;background:linear-gradient(90deg,rgba(255,255,255,.16),rgba(255,255,255,.02) 48%,rgba(255,255,255,.10))}
.sidebar{width:var(--sidebar-w);min-width:var(--sidebar-w);background:rgba(255,250,240,.66);border-right:1px solid rgba(255,255,255,.76);box-shadow:14px 0 44px rgba(72,43,10,.07),1px 0 0 rgba(255,255,255,.70) inset;backdrop-filter:blur(26px) saturate(1.25);overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:3px}
[data-theme="dark"] .sidebar{background:rgba(18,15,10,.68);border-color:rgba(255,255,255,.09);box-shadow:14px 0 46px rgba(0,0,0,.28)}
.side-title{padding:10px 12px 8px;color:var(--fg3);font-size:11px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.side-item{position:relative;display:flex;align-items:center;gap:8px;min-height:36px;padding:8px 10px 8px 14px;border-radius:10px;color:var(--fg2);font-size:13px;font-weight:700;cursor:pointer;transition:all .18s}
.side-item::before{content:'';position:absolute;left:6px;top:9px;bottom:9px;width:2px;border-radius:2px;background:transparent;transition:all .18s}
.side-item:hover{background:rgba(255,255,255,.38);color:var(--fg);transform:translateX(1px)}
[data-theme="dark"] .side-item:hover{background:rgba(255,255,255,.06)}
.side-item.active{background:rgba(255,255,255,.64);color:var(--accent);font-weight:900;box-shadow:0 12px 26px rgba(183,121,31,.10),0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .side-item.active{background:rgba(255,255,255,.08)}
.side-item.active::before{top:7px;bottom:7px;background:linear-gradient(180deg,var(--accent),var(--accent2))}
.side-main{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.badge{font-size:10px;padding:1px 7px;border-radius:12px;background:rgba(32,26,18,.06);color:var(--fg3);font-weight:800;border:1px solid rgba(32,26,18,.06);flex-shrink:0}
.side-item.active .badge{background:linear-gradient(180deg,var(--accent),var(--accent2));color:#fff;border-color:transparent}
.sub-list{margin-left:10px;padding-left:8px;border-left:1px solid var(--border);display:none}.sub-list.open{display:block}
.sub-item{padding:6px 8px;border-radius:9px;font-size:12.5px;color:var(--fg3);cursor:pointer;line-height:1.45;margin:2px 0}
.sub-item:hover{background:rgba(255,255,255,.34);color:var(--fg)}.sub-item.active{background:var(--accent-soft);color:var(--accent);font-weight:850}
.main{flex:1;overflow-y:auto;padding:32px 40px 64px;background:linear-gradient(180deg,rgba(255,255,255,.26),rgba(255,255,255,.04))}
.content-header{margin-bottom:24px;animation:fadeUp .35s ease}
.content-header h1{font-size:27px;line-height:1.3;font-weight:950;background:linear-gradient(135deg,var(--fg) 50%,var(--accent));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.subtitle{margin-top:5px;color:var(--fg3);font-size:13px}
.hero,.section-card,.panel,.quiz-item,.card-face,.search-result,.mentor-card,.score-card,.lv-block,.table{background:rgba(255,250,240,.72);border:1px solid rgba(255,255,255,.78);box-shadow:var(--shadow-md),0 1px 0 rgba(255,255,255,.82) inset;backdrop-filter:blur(22px) saturate(1.25);border-radius:var(--radius);animation:fadeUp .35s ease}
[data-theme="dark"] .hero,[data-theme="dark"] .section-card,[data-theme="dark"] .panel,[data-theme="dark"] .quiz-item,[data-theme="dark"] .card-face,[data-theme="dark"] .search-result,[data-theme="dark"] .mentor-card,[data-theme="dark"] .score-card,[data-theme="dark"] .lv-block,[data-theme="dark"] .table{background:rgba(24,20,14,.68);border-color:rgba(255,255,255,.09);box-shadow:0 24px 68px rgba(0,0,0,.38),0 1px 0 rgba(255,255,255,.08) inset}
.hero:hover,.section-card:hover,.panel:hover,.search-result:hover,.mentor-card:hover{border-color:rgba(183,121,31,.30);transform:translateY(-2px)}
.hero{padding:32px 36px;margin-bottom:20px;position:relative;overflow:hidden}
.hero::after{content:'';position:absolute;right:-80px;top:-90px;width:220px;height:220px;border-radius:50%;background:radial-gradient(circle,rgba(243,177,63,.32),transparent 70%)}
.kicker{font-size:11px;font-weight:950;color:var(--accent);letter-spacing:.9px;text-transform:uppercase;margin-bottom:8px}
.hero h2{font-size:29px;line-height:1.28;font-weight:950;margin-bottom:10px}.hero p{color:var(--fg2);font-size:14.5px;line-height:1.9;max-width:920px}
.pill-row,.md-pill-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.pill,.md-pill{padding:4px 10px;border-radius:20px;background:var(--accent-soft);border:1px solid var(--accent-glow);color:var(--accent);font-size:12px;font-weight:900}
.mentor-strip,.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px;margin:0 0 20px}
.mentor-card,.panel,.section-card{padding:22px 24px}
.mentor-card strong{display:block;font-size:13px;font-weight:900;color:var(--fg);margin-bottom:5px}.mentor-card p{font-size:12.8px;color:var(--fg2);line-height:1.65;margin:0}
.panel h3,.section-card h2{font-size:17px;font-weight:900;margin-bottom:12px;display:flex;align-items:center;gap:8px}.panel h3::before,.section-card h2::before{content:'';width:3px;height:18px;background:linear-gradient(180deg,var(--accent),var(--accent2));border-radius:2px}
.panel p,.section-card p{color:var(--fg2);font-size:14px;line-height:1.85;margin:8px 0}.panel ul,.section-card ul,.section-card ol{margin:8px 0 8px 20px;color:var(--fg2);font-size:14px}.panel li,.section-card li{margin:5px 0;line-height:1.75}
.answer-framework,.score-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px;margin:12px 0 4px}
.framework-step,.score-card,.source-item,pre,.timer,.table th{background:rgba(255,255,255,.50);border:1px solid rgba(255,255,255,.78);box-shadow:0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .framework-step,[data-theme="dark"] .score-card,[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .timer,[data-theme="dark"] .table th{background:rgba(255,255,255,.07);border-color:rgba(255,255,255,.10);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.framework-step{border-radius:10px;padding:10px 12px;color:var(--accent);font-size:12.5px;font-weight:900;line-height:1.45}
.score-card{padding:12px 14px;border-radius:10px}.score-card strong{display:block;font-size:13px;color:var(--fg);margin-bottom:4px}.score-card p{font-size:12.8px;color:var(--fg2);line-height:1.6;margin:0}
.microcopy{margin-top:10px;padding:11px 13px;border-radius:10px;background:var(--blue-soft);border-left:3px solid var(--blue);font-size:13px;color:var(--fg2);line-height:1.7}
.source-list{display:flex;flex-direction:column;gap:8px}.source-item{padding:9px 10px;border-radius:10px;font-family:var(--font-mono);font-size:12px;color:var(--fg2);line-height:1.45;word-break:break-all}
.checkline{display:flex;gap:8px;padding:8px 0;border-bottom:1px solid var(--border);font-size:13.5px;color:var(--fg2)}.checkline:last-child{border-bottom:0}.checkline span:first-child{width:18px;height:18px;border-radius:6px;background:var(--green-soft);color:var(--green);display:grid;place-items:center;font-size:11px;font-weight:950;flex-shrink:0;margin-top:2px}
.markdown-doc{max-width:960px;margin:0 auto;background:rgba(255,250,240,.78);border:1px solid rgba(255,255,255,.82);border-radius:var(--radius);box-shadow:var(--shadow-md),0 1px 0 rgba(255,255,255,.82) inset;padding:36px 42px;position:relative;overflow:hidden;animation:fadeUp .35s;backdrop-filter:blur(26px) saturate(1.24)}
[data-theme="dark"] .markdown-doc{background:rgba(24,20,14,.72);border-color:rgba(255,255,255,.10)}
.markdown-doc h1{font-size:32px;line-height:1.25;font-weight:950;color:var(--fg);margin:4px 0 12px}.markdown-doc h2{font-size:21px;line-height:1.35;font-weight:900;color:var(--fg);margin:32px 0 12px;padding-top:18px;border-top:1px solid var(--border)}.markdown-doc h3{font-size:15px;font-weight:900;color:var(--fg);margin:18px 0 8px}
.markdown-doc p{font-size:15px;color:var(--fg2);line-height:1.9;margin:10px 0}.markdown-doc ul,.markdown-doc ol{margin:10px 0 10px 22px;color:var(--fg2);font-size:14.5px;line-height:1.85}.markdown-doc li{margin:5px 0}
.markdown-doc blockquote{margin:18px 0;padding:12px 16px;border-left:4px solid var(--accent);background:var(--accent-soft);border-radius:0 10px 10px 0;color:var(--fg2)}
.md-kicker{font-size:11px;font-weight:950;letter-spacing:.8px;text-transform:uppercase;color:var(--accent);margin-bottom:8px}
.md-section{padding:2px 0 12px;border-radius:10px;transition:all .2s}.md-section.active{background:linear-gradient(90deg,rgba(183,121,31,.13),rgba(37,99,235,.06),transparent 78%);padding-left:16px;margin-left:-16px;box-shadow:inset 3px 0 0 var(--accent)}
.lv-block{margin:12px 0;overflow:hidden;border-radius:12px}.lv-block.lv1{border-left:4px solid var(--lv1)}.lv-block.lv2{border-left:4px solid var(--lv2)}.lv-block.lv3{border-left:4px solid var(--lv3)}
.lv-header{display:flex;align-items:center;gap:8px;padding:12px 16px;font-size:14px;font-weight:900;cursor:pointer;user-select:none}.lv-block.lv1 .lv-header{background:var(--lv1-soft);color:var(--lv1)}.lv-block.lv2 .lv-header{background:var(--lv2-soft);color:var(--lv2)}.lv-block.lv3 .lv-header{background:var(--lv3-soft);color:var(--lv3)}
.lv-arrow{font-size:10px;transition:transform .2s;color:var(--fg3)}.lv-header.open .lv-arrow{transform:rotate(90deg)}.lv-tag{font-size:10px;padding:2px 8px;border-radius:10px;color:#fff;letter-spacing:.5px;text-transform:uppercase}.lv1 .lv-tag{background:var(--lv1)}.lv2 .lv-tag{background:var(--lv2)}.lv3 .lv-tag{background:var(--lv3)}
.lv-body{max-height:0;overflow:hidden;transition:max-height .34s cubic-bezier(.4,0,.2,1);padding:0 16px}.lv-body.open{max-height:4200px;padding:0 16px 16px}.lv-body p,.lv-body li{color:var(--fg2);font-size:14px;line-height:1.85}.lv-body ul,.lv-body ol{margin:8px 0 8px 20px}.lv-body strong{color:var(--fg)}
code.inline,.markdown-doc code{font-family:var(--font-mono);font-size:12.5px;color:var(--accent);background:var(--code-bg);border:1px solid var(--code-border);border-radius:5px;padding:2px 6px}
pre{border-radius:12px;padding:16px 18px;overflow:auto;font-family:var(--font-mono);font-size:12.5px;line-height:1.65;margin:12px 0;color:var(--fg)}
.quiz-item{margin:10px 0;overflow:hidden}.quiz-q{padding:14px 18px;display:flex;gap:10px;align-items:flex-start;cursor:pointer;font-weight:850;font-size:14px}.quiz-q:hover{background:rgba(255,255,255,.28)}
.q-num{width:24px;height:24px;border-radius:7px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:11px;flex-shrink:0}.q-text{flex:1}.q-toggle{font-size:10px;color:var(--fg3);margin-top:6px;transition:transform .2s}.q-toggle.open{transform:rotate(90deg)}
.quiz-body{max-height:0;overflow:hidden;transition:max-height .28s}.quiz-body.open{max-height:900px}.quiz-hint{margin:0 18px 14px;padding:14px 16px;background:var(--warn-soft);border-left:3px solid var(--warn);border-radius:10px;font-size:13.5px;color:var(--fg2);line-height:1.75}
.quiz-btns{display:flex;gap:8px;margin:0 18px 14px}.quiz-btn{padding:5px 14px;border-radius:9px;font-size:12px;font-weight:900;color:#fff}.quiz-btn.mastered{background:var(--green)}.quiz-btn.review{background:var(--warn)}
.quiz-status{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:900;margin-top:3px}.status-mastered{background:var(--green-soft);color:var(--green);border:1px solid rgba(31,157,114,.22)}.status-review{background:var(--warn-soft);color:var(--warn);border:1px solid rgba(217,119,6,.22)}
.nav-bar{display:flex;justify-content:space-between;gap:12px;margin-top:26px;padding-top:18px;border-top:1px solid var(--border)}
.nav-btn,.tool-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 16px;border-radius:10px;font-size:13px;font-weight:900;border:1px solid var(--border);color:var(--fg2);transition:all .2s;box-shadow:0 10px 24px rgba(72,43,10,.08),0 1px 0 rgba(255,255,255,.55) inset}
.nav-btn:hover,.tool-btn:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}.nav-btn.primary,.tool-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 14px 30px var(--accent-glow),0 1px 0 rgba(255,255,255,.24) inset}.nav-btn.primary:hover,.tool-btn.primary:hover{background:var(--accent2);color:#fff}
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:18px}.timer{font-family:var(--font-mono);font-size:21px;font-weight:900;letter-spacing:1px;color:var(--accent);border-radius:10px;padding:4px 12px;min-width:88px;text-align:center}
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(350px,1fr));gap:16px}.card{perspective:1200px;height:330px;cursor:pointer;animation:fadeUp .3s ease}.card-inner{position:relative;width:100%;height:100%;transition:transform .55s;transform-style:preserve-3d}.card.flipped .card-inner{transform:rotateY(180deg)}
.card-face{position:absolute;inset:0;backface-visibility:hidden;overflow:auto}.card-front{padding:20px;display:flex;flex-direction:column}.card-back{transform:rotateY(180deg);padding:18px;font-size:13px}.card-idx{font-size:11px;font-weight:950;color:var(--fg3);letter-spacing:1px;text-transform:uppercase;margin-bottom:8px}.card-title{font-size:15px;font-weight:900;line-height:1.6;flex:1}.card-tag{align-self:flex-start;margin-top:12px;padding:3px 10px;border-radius:16px;background:var(--accent-soft);color:var(--accent);font-size:11px;font-weight:950}
.card-back h4{font-size:12px;font-weight:950;color:var(--accent);margin:10px 0 4px;letter-spacing:.5px;text-transform:uppercase}.card-back h4:first-child{margin-top:0}.card-back p{font-size:13px;color:var(--fg2);line-height:1.75}.code-link{font-family:var(--font-mono);font-size:12px;color:var(--fg3);word-break:break-all}
.card-actions{display:flex;gap:8px;margin-top:12px;border-top:1px solid var(--border);padding-top:10px}.card-action{padding:5px 12px;border-radius:9px;font-size:11px;font-weight:950;color:#fff}.card-action.practice{background:var(--green)}.card-action.review{background:var(--warn)}
.table{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden;font-size:13.5px}.table th{color:var(--fg3);text-align:left;padding:10px 14px;font-size:12px;text-transform:uppercase}.table td{padding:10px 14px;border-top:1px solid var(--border);color:var(--fg2);vertical-align:top}
.search-result{padding:14px 18px;margin:8px 0;cursor:pointer}.search-result:hover{border-color:var(--accent)}.sr-mode{font-size:10px;font-weight:950;color:var(--accent);letter-spacing:.6px;text-transform:uppercase}.sr-title{font-size:14px;font-weight:900;color:var(--fg);margin-top:2px}.sr-snippet{font-size:13px;color:var(--fg3);line-height:1.55;margin-top:4px}mark{background:var(--accent-glow);color:var(--accent);border-radius:3px;padding:1px 3px;font-weight:900}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@media(max-width:1080px){.search-box{width:170px}.search-box:focus{width:220px}.main{padding:24px}.card-grid{grid-template-columns:1fr}}
@media(max-width:760px){
 body::before{display:none}.topnav{height:auto;min-height:var(--topnav-h);padding:10px 12px;flex-direction:column;align-items:stretch}.brand{width:100%;margin-right:0}.brand-sub{display:none}.mode-tabs{flex-direction:column}.mode-btn{width:100%;padding:8px 10px}.repo-link{justify-content:center}.search-box,.search-box:focus{width:100%}.app{display:block;height:auto;min-height:calc(100dvh - 180px)}.sidebar{display:none}.main{padding:16px 14px 48px}.hero,.section-card,.panel,.markdown-doc{padding:18px 16px}.hero h2{font-size:23px}.content-header h1{font-size:22px}.grid,.mentor-strip{grid-template-columns:1fr}.nav-bar{flex-direction:column}.nav-btn{width:100%}.card{height:390px}.quiz-q{padding:12px}.quiz-btns{flex-direction:column}.quiz-btn{width:100%;padding:8px 12px}.table{display:block;overflow:auto;white-space:nowrap}
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="topnav"&gt;
 &lt;div class="brand"&gt;
 &lt;div class="brand-icon" aria-label="Blockchain"&gt;
 &lt;svg viewBox="0 0 64 64" role="img" aria-hidden="true"&gt;
 &lt;rect x="9" y="10" width="18" height="18" rx="5" fill="#201a12" opacity=".92"/&gt;
 &lt;rect x="37" y="10" width="18" height="18" rx="5" fill="#201a12" opacity=".82"/&gt;
 &lt;rect x="23" y="36" width="18" height="18" rx="5" fill="#201a12" opacity=".72"/&gt;
 &lt;path d="M27 19h10M46 28l-9 8M23 36l-7-8" fill="none" stroke="#fff4d6" stroke-width="4" stroke-linecap="round"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div&gt;&lt;span class="brand-text"&gt;Nakamoto共识&lt;/span&gt;&lt;span class="brand-sub"&gt;（Go语言）学习&lt;/span&gt;&lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="mode-tabs"&gt;
 &lt;button class="mode-btn active" data-mode="intro" onclick="switchMode('intro')"&gt;前言&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="learn" onclick="switchMode('learn')"&gt;知识学习&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="breakdown" onclick="switchMode('breakdown')"&gt;项目拆解&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="interview" onclick="switchMode('interview')"&gt;面试模拟&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="scenario" onclick="switchMode('scenario')"&gt;场景还原&lt;/button&gt;
 &lt;/div&gt;
 &lt;a class="repo-link" href="https://github.com/Kunyanli230/Learn_ProofOfWork" target="_blank" rel="noopener"&gt;GitHub 仓库&lt;/a&gt;
 &lt;div class="search-wrap"&gt;&lt;span class="search-icon"&gt;⌕&lt;/span&gt;&lt;input id="searchInput" class="search-box" type="text" placeholder="搜索内容..." oninput="handleSearch(this.value)"&gt;&lt;/div&gt;
 &lt;button class="theme-btn" onclick="toggleTheme()" title="切换主题"&gt;&lt;span id="themeIcon"&gt;☽&lt;/span&gt;&lt;/button&gt;
 &lt;div class="progress-pill"&gt;&lt;span class="dot"&gt;&lt;/span&gt;&lt;span id="progressText"&gt;0/10&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="app" id="app"&gt;&lt;/div&gt;
&lt;script&gt;
const STORE="study-blockchain-progress-v1";
const S={mode:"intro",sec:0,ch:0,topic:0,dim:0,q:""};

const introData={
 title:"Nakamoto共识（Go语言）10天项目学习",
 desc:"从 Block 结构开始，用 10 个渐进步骤构建一个比特币式区块链系统。页面把原始文档拆成前言、知识学习、项目拆解、面试模拟和场景还原，目标是让你既能写出项目，也能把 PoW、UTXO、Merkle 树、P2P 同步和 Nakamoto 共识讲清楚。",
 pillars:[
 {title:"项目介绍",text:"这是一个 Go 语言实现的 Nakamoto 共识教学项目。代码从最小区块链起步，逐步加入 PoW、gob 序列化、BoltDB 持久化、CLI、UTXO 交易、钱包、Merkle 树和 P2P 网络，最后形成一条能同步、能交易、能解释共识规则的链。"},
 {title:"前置要求",text:"建议具备 Go 基础语法、哈希、序列化、KV 存储、命令行参数、ECDSA、TCP 网络和基础数据结构。区块链背景可以在学习过程中补齐。"},
 {title:"Level 1：能跑能演示",text:"能启动节点，创建钱包，生成创世区块，发起交易，同步区块，看到完整链路输出。"},
 {title:"Level 2：面试级理解",text:"能讲清区块结构、PoW 挖矿、UTXO、Merkle 树、P2P 消息和最长链规则。"},
 {title:"Level 3：抗追问能力",text:"能回答 targetBit、双花、分叉、网络分区、51% 攻击、地址校验和 SPV 证明等追问。"},
 {title:"Level 4：可独立复刻",text:"能关掉文档，从零复刻 Block、PoW、BoltDB、Transaction、Wallet、MerkleTree 和 P2P 网络。"},
 {title:"Level 5：分布式共识大师",text:"能把 Nakamoto 共识抽象成 PoW、最长链、概率最终性和开放网络安全模型。"},
 {title:"学习方法",text:"先看前言建立地图，再逐章学知识点，用 10 天项目拆解追源码，最后用面试卡片和场景题训练表达。"},
 {title:"最终产出",text:"学完后形成一张 Nakamoto 共识链路图、一份 10 步复刻路线、15 道高频追问答案、5 条简历亮点和一套共识系统回答框架。"}
 ],
 prerequisites:["Go 基础语法与错误处理","crypto/sha256 哈希计算","encoding/gob 序列化","BoltDB 嵌入式 KV 数据库","flag 命令行参数解析","ECDSA 椭圆曲线签名","net 包 TCP 网络编程","链表、树、哈希等基础数据结构"],
 levels:[
 {title:"Level 1：能跑能演示",standard:"能从零写 Block + Blockchain 并输出区块信息。",proof:"能画出 Block 结构体和链式连接关系。",next:"加入 PoW 挖矿。"},
 {title:"Level 2：面试级理解",standard:"能把项目讲成 Block → PoW → BoltDB → CLI → UTXO 的工程演化。",proof:"能回答每个模块为什么需要前一个模块。",next:"准备 UTXO、签名和网络同步追问。"},
 {title:"Level 3：抗追问能力",standard:"能解释网络分区时节点如何重新同步。",proof:"能把回答落到源码入口：handleVersion、handleInv、sendBlock。",next:"把核心模块背到可以复刻。"},
 {title:"Level 4：可独立复刻",standard:"能从零写出最小可运行区块链系统。",proof:"能还原目录结构、Block 结构体、PoW 验证和 P2P 协议。",next:"抽象成分布式共识设计框架。"},
 {title:"Level 5：分布式共识大师",standard:"能从项目上升到通用异步共识方法论。",proof:"能主动讨论 PoW、最长链、概率最终性和 51% 攻击。",next:"进入异步 BFT 学习。"}
 ],
 method:[
 {title:"先跑通",text:"用 CLI 跑出区块、交易和节点同步，先获得系统手感。"},
 {title:"再拆层",text:"按数据结构、共识、存储、交易、密码学、网络六条线拆源码。"},
 {title:"追链路",text:"把 createblockchain、addblock、send、printchain、node sync 串成端到端流程。"},
 {title:"背表达",text:"每个知识点都整理成 Level 1 概念、Level 2 源码、Level 3 追问。"},
 {title:"画图复盘",text:"用图表达区块连接、PoW 目标、UTXO 消费、Merkle Proof 和 P2P 同步。"},
 {title:"面试冲刺",text:"把项目介绍、源码入口、故障场景和扩展方案练到可以稳定输出。"}
 ],
 answerFrame:["一句话结论","项目位置","源码入口","核心机制","安全边界","追问扩展"],
 scorecard:[
 {title:"链路完整",text:"能从命令行入口追到数据存储和网络同步。"},
 {title:"源码可信",text:"每个结论都能指到核心文件、结构体和函数。"},
 {title:"机制清楚",text:"能解释 PoW、UTXO、Merkle、P2P 的安全意义。"},
 {title:"追问稳",text:"能处理分叉、双花、网络分区和 51% 攻击问题。"}
 ],
 outputs:["Bitcoin/Nakamoto 核心链路图","Block + PoW + UTXO 关系图","5 条简历亮点","15 道高频面试追问答案","10 步复刻路线图","Nakamoto 共识通用回答框架"]
};

const learnData=[
 {title:"第1章：区块与链",topics:[
 {q:"Block 结构体包含哪些字段？每个字段的作用是什么？",lv1:`&lt;p&gt;区块是区块链的最小存储单元，核心字段包括 Height、PrevBlockHash、Data、Timestamp 和 Hash。Height 表示高度，PrevBlockHash 负责连接前一个区块，Data 保存交易或业务数据，Timestamp 记录创建时间，Hash 是当前区块内容摘要。&lt;/p&gt;</description></item><item><title>视频Feed流系统（hard）学习</title><link>https://go.botsarena.tech/docs/project-study/study-feed-hard/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://go.botsarena.tech/docs/project-study/study-feed-hard/</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN" data-theme="light"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;title&gt;视频Feed流系统（hard）学习&lt;/title&gt;
&lt;style&gt;
:root{
 --bg:#fafafa;--bg2:#f0f0f0;--bg3:#e4e4e7;--fg:#18181b;--fg2:#71717a;--fg3:#a1a1aa;
 --card:#fff;--border:#e4e4e7;--accent:#6366f1;--accent2:#4f46e5;--accent-soft:#eef2ff;--accent-glow:rgba(99,102,241,.16);
 --success:#22c55e;--success-soft:#f0fdf4;--warn:#f59e0b;--warn-soft:#fffbeb;--danger:#ef4444;--danger-soft:#fef2f2;--info:#3b82f6;--info-soft:#eff6ff;
 --code-bg:#f4f4f5;--code-border:#e4e4e7;--shadow-sm:0 1px 2px rgba(0,0,0,.05);--shadow-md:0 4px 14px rgba(0,0,0,.08);
 --sidebar-w:292px;--topnav-h:56px;--radius:10px;--radius-sm:6px;--font-body:'Noto Sans SC',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;--font-mono:'JetBrains Mono','Fira Code',Consolas,monospace;
 --lv1:#22c55e;--lv1-soft:#f0fdf4;--lv2:#3b82f6;--lv2-soft:#eff6ff;--lv3:#f59e0b;--lv3-soft:#fffbeb;
 --noise:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
}
[data-theme="dark"]{
 --bg:#09090b;--bg2:#18181b;--bg3:#27272a;--fg:#fafafa;--fg2:#a1a1aa;--fg3:#71717a;
 --card:#18181b;--border:#27272a;--accent:#818cf8;--accent2:#6366f1;--accent-soft:#1e1b4b;--accent-glow:rgba(129,140,248,.14);
 --success-soft:#052e16;--warn-soft:#451a03;--danger-soft:#450a0a;--info-soft:#172554;--code-bg:#1e1e22;--code-border:#2e2e33;--shadow-sm:0 1px 2px rgba(0,0,0,.35);--shadow-md:0 4px 16px rgba(0,0,0,.45);
 --lv1-soft:#052e16;--lv2-soft:#172554;--lv3-soft:#451a03;
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased}
body{min-height:100vh;background:var(--bg);color:var(--fg);font-family:var(--font-body);font-size:15px;line-height:1.7;transition:background .25s,color .25s}
a{color:var(--accent);text-decoration:none}
button{border:0;background:none;color:inherit;font:inherit;cursor:pointer}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-thumb{background:var(--fg3);border-radius:10px}
.topnav{height:var(--topnav-h);display:flex;align-items:center;gap:10px;padding:0 20px;background:var(--card);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}
.brand{display:flex;align-items:center;gap:10px;margin-right:auto;white-space:nowrap}
.brand-icon{width:32px;height:32px;border-radius:9px;background:#e0f7fa;border:1px solid rgba(15,118,140,.18);display:grid;place-items:center;box-shadow:0 2px 8px var(--accent-glow);overflow:hidden}
.brand-icon svg{width:30px;height:30px}
.brand-text{font-size:15px;font-weight:800}.brand-sub{font-size:11px;color:var(--fg3);margin-left:4px}
.mode-tabs{display:flex;background:var(--bg2);border-radius:8px;padding:3px;gap:2px}
.mode-btn{padding:5px 14px;border-radius:6px;font-size:13px;font-weight:600;color:var(--fg2);transition:all .2s}
.mode-btn.active{background:var(--accent);color:#fff;box-shadow:0 2px 8px var(--accent-glow)}
.mode-btn:hover{background:var(--bg3);color:var(--fg)}
.mode-btn.active:hover{background:var(--accent);color:#fff}
.repo-link,.light-link{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid var(--border);border-radius:8px;background:var(--bg2);color:var(--fg2);font-size:13px;font-weight:600;line-height:1;white-space:nowrap;transition:all .2s}
.repo-link:hover,.light-link:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.search-wrap{position:relative}
.search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);font-size:13px;color:var(--fg3);pointer-events:none}
.search-box{width:210px;padding:6px 12px 6px 32px;border:1px solid var(--border);border-radius:8px;background:var(--bg2);color:var(--fg);font-size:13px;outline:none;transition:all .2s}
.search-box:focus{width:280px;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.theme-btn{width:32px;height:32px;border-radius:8px;color:var(--fg2);display:grid;place-items:center;font-size:16px}.theme-btn:hover{background:var(--bg2);color:var(--fg)}
.progress-pill{display:flex;align-items:center;gap:6px;padding:4px 12px;border-radius:20px;background:var(--success-soft);border:1px solid rgba(34,197,94,.24);font-size:12px;font-weight:700;color:var(--success)}
.dot{width:6px;height:6px;border-radius:50%;background:var(--success)}
.app{display:flex;height:calc(100vh - var(--topnav-h));overflow:hidden}
.sidebar{width:var(--sidebar-w);min-width:var(--sidebar-w);background:var(--card);border-right:1px solid var(--border);overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:3px}
.side-title{padding:8px 10px 4px;color:var(--fg3);font-size:11px;font-weight:900;letter-spacing:.8px;text-transform:uppercase}
.side-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:var(--radius-sm);color:var(--fg2);font-size:13px;cursor:pointer;transition:all .16s}
.side-item:hover{background:var(--bg2);color:var(--fg)}
.side-item.active{background:var(--accent-soft);color:var(--accent);font-weight:800}
.side-main{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.badge{font-size:10px;padding:1px 7px;border-radius:12px;background:var(--bg3);color:var(--fg3);font-weight:700;flex-shrink:0}
.side-item.active .badge{background:var(--accent);color:#fff}
.sub-list{margin-left:10px;padding-left:8px;border-left:1px solid var(--border);display:none}
.sub-list.open{display:block}
.sub-item{padding:5px 8px;border-radius:var(--radius-sm);font-size:12.5px;color:var(--fg3);cursor:pointer;line-height:1.45;margin:1px 0}
.sub-item:hover{background:var(--bg2);color:var(--fg)}
.sub-item.active{background:var(--accent-soft);color:var(--accent);font-weight:700}
.main{flex:1;overflow-y:auto;padding:32px 40px 64px}
.content-header{margin-bottom:24px;animation:fadeUp .35s ease}
.content-header h1{font-size:26px;line-height:1.3;font-weight:900;background:linear-gradient(135deg,var(--fg) 58%,var(--accent));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.subtitle{margin-top:5px;color:var(--fg3);font-size:13px}
.hero,.section-card,.panel{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);animation:fadeUp .35s ease}
.hero{padding:30px 34px;margin-bottom:20px}
.kicker{font-size:11px;font-weight:900;color:var(--accent);letter-spacing:.8px;text-transform:uppercase;margin-bottom:8px}
.hero h2{font-size:28px;line-height:1.28;font-weight:900;margin-bottom:10px}
.hero p{color:var(--fg2);font-size:14.5px;line-height:1.85;max-width:900px}
.pill-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.pill{padding:4px 10px;border-radius:20px;background:var(--accent-soft);border:1px solid var(--accent-glow);color:var(--accent);font-size:12px;font-weight:800}
.mentor-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px;margin:0 0 20px}
.mentor-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm);animation:fadeUp .3s ease}
.mentor-card strong{display:block;font-size:13px;font-weight:850;color:var(--fg);margin-bottom:5px}
.mentor-card p{font-size:12.8px;color:var(--fg2);line-height:1.65;margin:0}
.answer-framework{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin:12px 0 4px}
.framework-step{background:var(--accent-soft);border:1px solid var(--accent-glow);border-radius:var(--radius-sm);padding:10px 12px;color:var(--accent);font-size:12.5px;font-weight:850;line-height:1.45}
.score-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px;margin-top:10px}
.score-card{padding:12px 14px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg2)}
.score-card strong{display:block;font-size:13px;color:var(--fg);margin-bottom:4px}
.score-card p{font-size:12.8px;color:var(--fg2);line-height:1.6;margin:0}
.microcopy{margin-top:10px;padding:10px 12px;border-radius:var(--radius-sm);background:var(--info-soft);border-left:3px solid var(--info);font-size:13px;color:var(--fg2);line-height:1.7}
.markdown-doc{max-width:940px;margin:0 auto;animation:fadeUp .35s}
.markdown-doc h1{font-size:30px;line-height:1.25;font-weight:900;color:var(--fg);margin:4px 0 12px}
.markdown-doc h2{font-size:21px;line-height:1.35;font-weight:850;color:var(--fg);margin:32px 0 12px;padding-top:18px;border-top:1px solid var(--border)}
.markdown-doc h3{font-size:15px;font-weight:850;color:var(--fg);margin:18px 0 8px}
.markdown-doc p{font-size:15px;color:var(--fg2);line-height:1.9;margin:10px 0}
.markdown-doc ul,.markdown-doc ol{margin:10px 0 10px 22px;color:var(--fg2);font-size:14.5px;line-height:1.85}
.markdown-doc li{margin:5px 0}
.markdown-doc blockquote{margin:18px 0;padding:12px 16px;border-left:4px solid var(--accent);background:var(--accent-soft);border-radius:0 var(--radius-sm) var(--radius-sm) 0;color:var(--fg2)}
.markdown-doc hr{border:0;border-top:1px solid var(--border);margin:26px 0}
.markdown-doc code{font-family:var(--font-mono);font-size:13px;color:var(--accent);background:var(--code-bg);border:1px solid var(--code-border);border-radius:4px;padding:2px 6px}
.md-kicker{font-size:11px;font-weight:900;letter-spacing:.8px;text-transform:uppercase;color:var(--accent);margin-bottom:8px}
.md-section{padding:2px 0 8px;border-radius:var(--radius-sm)}
.md-section.active{background:linear-gradient(90deg,var(--accent-soft),transparent 72%);padding-left:14px;margin-left:-14px}
.md-pill-row{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 22px}
.md-pill{padding:4px 10px;border-radius:20px;background:var(--accent-soft);border:1px solid var(--accent-glow);color:var(--accent);font-size:12px;font-weight:800}
/* ═══════════ PREMIUM GLASS SKIN ═══════════ */
:root{
 --glass:rgba(255,255,255,.72);
 --glass-strong:rgba(255,255,255,.86);
 --glass-soft:rgba(255,255,255,.48);
 --glass-border:rgba(255,255,255,.66);
 --hairline:rgba(24,24,27,.09);
 --shadow-glass:0 18px 46px rgba(15,23,42,.10),0 1px 0 rgba(255,255,255,.72) inset;
 --shadow-float:0 10px 28px rgba(15,23,42,.08);
}
[data-theme="dark"]{
 --glass:rgba(24,24,27,.64);
 --glass-strong:rgba(39,39,42,.78);
 --glass-soft:rgba(39,39,42,.42);
 --glass-border:rgba(255,255,255,.10);
 --hairline:rgba(255,255,255,.08);
 --shadow-glass:0 18px 48px rgba(0,0,0,.34),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-float:0 12px 34px rgba(0,0,0,.28);
}
body{background:linear-gradient(180deg,#f7f8fb 0%,#eef2f7 46%,#fbfcfd 100%) fixed}
[data-theme="dark"] body{background:linear-gradient(180deg,#09090b 0%,#111318 48%,#08090b 100%) fixed}
body::before{content:'';position:fixed;inset:0;background:var(--noise);pointer-events:none;z-index:9999;opacity:.24;mix-blend-mode:multiply}
[data-theme="dark"] body::before{opacity:.12;mix-blend-mode:screen}
.topnav{background:var(--glass-strong);border-bottom:1px solid var(--glass-border);box-shadow:0 10px 30px rgba(15,23,42,.06);backdrop-filter:blur(24px) saturate(1.35);-webkit-backdrop-filter:blur(24px) saturate(1.35)}
.sidebar{background:var(--glass);border-right:1px solid var(--glass-border);box-shadow:1px 0 0 var(--hairline),12px 0 38px rgba(15,23,42,.04);backdrop-filter:blur(26px) saturate(1.35);-webkit-backdrop-filter:blur(26px) saturate(1.35)}
.mode-tabs,.search-box,.repo-link,.light-link,.theme-btn{background:var(--glass-soft);border:1px solid var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.45) inset}
.mode-btn.active{background:linear-gradient(180deg,#24242a,#111113);color:#fff;box-shadow:0 8px 20px rgba(17,17,19,.18),0 1px 0 rgba(255,255,255,.18) inset}
[data-theme="dark"] .mode-btn.active{background:linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,.10));box-shadow:0 8px 24px rgba(0,0,0,.32),0 1px 0 rgba(255,255,255,.16) inset}
.hero,.section-card,.panel,.quiz-item,.card-face,.search-result,.mentor-card,.score-card,.lv-block{background:var(--glass);border:1px solid var(--glass-border);box-shadow:var(--shadow-glass);backdrop-filter:blur(22px) saturate(1.28);-webkit-backdrop-filter:blur(22px) saturate(1.28)}
.hero:hover,.section-card:hover,.panel:hover,.search-result:hover,.mentor-card:hover{box-shadow:var(--shadow-glass),0 0 0 1px rgba(99,102,241,.10);transform:translateY(-1px)}
.source-item,pre,.framework-step,.md-pill,.pill,.sub-item.active,.side-item.active,.badge{background:rgba(255,255,255,.56);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.55) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .side-item.active,[data-theme="dark"] .badge{background:rgba(255,255,255,.07);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.markdown-doc blockquote,.microcopy,.progress-pill{background:var(--glass-soft);border:1px solid var(--glass-border);box-shadow:var(--shadow-float);backdrop-filter:blur(18px) saturate(1.25);-webkit-backdrop-filter:blur(18px) saturate(1.25)}
.markdown-doc h1,.content-header h1{text-shadow:0 1px 0 rgba(255,255,255,.35)}
[data-theme="dark"] .markdown-doc h1,[data-theme="dark"] .content-header h1{text-shadow:0 1px 0 rgba(0,0,0,.35)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:16px;margin-bottom:20px}
.panel{padding:22px 24px}
.panel h3,.section-card h2{font-size:17px;font-weight:850;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.panel h3::before,.section-card h2::before{content:'';width:3px;height:18px;background:linear-gradient(180deg,var(--accent),var(--accent2));border-radius:2px}
.panel p,.section-card p{color:var(--fg2);font-size:14px;line-height:1.8;margin:8px 0}
.panel ul,.section-card ul,.section-card ol{margin:8px 0 8px 20px;color:var(--fg2);font-size:14px}
.panel li,.section-card li{margin:5px 0;line-height:1.7}
.source-list{display:flex;flex-direction:column;gap:8px}
.source-item{padding:9px 10px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg2);font-family:var(--font-mono);font-size:12px;color:var(--fg2);line-height:1.45;word-break:break-all}
.checkline{display:flex;gap:8px;padding:8px 0;border-bottom:1px solid var(--border);font-size:13.5px;color:var(--fg2)}
.checkline:last-child{border-bottom:0}.checkline span:first-child{width:18px;height:18px;border-radius:5px;background:var(--success-soft);color:var(--success);display:grid;place-items:center;font-size:11px;font-weight:900;flex-shrink:0;margin-top:2px}
.section-card{padding:28px 32px;margin-bottom:20px}
.lv-block{margin:12px 0;border-radius:var(--radius-sm);overflow:hidden;border:1px solid var(--border)}
.lv-block.lv1{border-left:3px solid var(--lv1)}.lv-block.lv2{border-left:3px solid var(--lv2)}.lv-block.lv3{border-left:3px solid var(--lv3)}
.lv-header{display:flex;align-items:center;gap:8px;padding:12px 16px;font-size:14px;font-weight:800;cursor:pointer;user-select:none}
.lv-block.lv1 .lv-header{background:var(--lv1-soft);color:var(--lv1)}.lv-block.lv2 .lv-header{background:var(--lv2-soft);color:var(--lv2)}.lv-block.lv3 .lv-header{background:var(--lv3-soft);color:var(--lv3)}
.lv-arrow{font-size:10px;transition:transform .2s;color:var(--fg3)}.lv-header.open .lv-arrow{transform:rotate(90deg)}
.lv-tag{font-size:10px;padding:2px 8px;border-radius:10px;color:#fff;letter-spacing:.5px;text-transform:uppercase}.lv1 .lv-tag{background:var(--lv1)}.lv2 .lv-tag{background:var(--lv2)}.lv3 .lv-tag{background:var(--lv3)}
.lv-body{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1);padding:0 16px}.lv-body.open{max-height:4000px;padding:0 16px 16px}
.lv-body p,.lv-body li{color:var(--fg2);font-size:14px;line-height:1.8}.lv-body ul,.lv-body ol{margin:8px 0 8px 20px}.lv-body strong{color:var(--fg)}
code.inline{background:var(--code-bg);border:1px solid var(--code-border);border-radius:4px;padding:2px 6px;color:var(--accent);font-family:var(--font-mono);font-size:12.5px}
pre{background:var(--code-bg);border:1px solid var(--code-border);border-radius:var(--radius);padding:16px 18px;overflow:auto;font-family:var(--font-mono);font-size:12.5px;line-height:1.6;margin:12px 0;color:var(--fg)}
.quiz-item{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);margin:10px 0;overflow:hidden;animation:fadeUp .25s ease}
.quiz-q{padding:14px 18px;display:flex;gap:10px;align-items:flex-start;cursor:pointer;font-weight:700;font-size:14px}.quiz-q:hover{background:var(--bg2)}
.q-num{width:24px;height:24px;border-radius:6px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:11px;flex-shrink:0}.q-text{flex:1}.q-toggle{font-size:10px;color:var(--fg3);margin-top:6px;transition:transform .2s}.q-toggle.open{transform:rotate(90deg)}
.quiz-body{max-height:0;overflow:hidden;transition:max-height .28s}.quiz-body.open{max-height:900px}
.quiz-hint{margin:0 18px 14px;padding:14px 16px;background:var(--warn-soft);border-left:3px solid var(--warn);border-radius:var(--radius-sm);font-size:13.5px;color:var(--fg2);line-height:1.7}
.quiz-btns{display:flex;gap:8px;margin:0 18px 14px}.quiz-btn{padding:5px 14px;border-radius:var(--radius-sm);font-size:12px;font-weight:800;color:#fff}.quiz-btn.mastered{background:var(--success)}.quiz-btn.review{background:var(--warn)}
.quiz-status{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:800;margin-top:3px}.status-mastered{background:var(--success-soft);color:var(--success);border:1px solid rgba(34,197,94,.22)}.status-review{background:var(--warn-soft);color:var(--warn);border:1px solid rgba(245,158,11,.22)}
.nav-bar{display:flex;justify-content:space-between;gap:12px;margin-top:26px;padding-top:18px;border-top:1px solid var(--border)}
.nav-btn,.tool-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:8px 16px;border-radius:var(--radius-sm);font-size:13px;font-weight:800;border:1px solid var(--border);color:var(--fg2);transition:all .2s}
.nav-btn:hover,.tool-btn:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.nav-btn.primary,.tool-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 2px 8px var(--accent-glow)}
.nav-btn.primary:hover,.tool-btn.primary:hover{background:var(--accent2);color:#fff}
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:18px}
.timer{font-family:var(--font-mono);font-size:21px;font-weight:800;letter-spacing:1px;color:var(--accent);background:var(--accent-soft);border-radius:var(--radius-sm);padding:4px 12px;min-width:88px;text-align:center}
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:16px}
.card{perspective:1200px;height:330px;cursor:pointer;animation:fadeUp .3s ease}.card-inner{position:relative;width:100%;height:100%;transition:transform .55s;transform-style:preserve-3d}.card.flipped .card-inner{transform:rotateY(180deg)}
.card-face{position:absolute;inset:0;backface-visibility:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);overflow:auto}.card-front{padding:20px;display:flex;flex-direction:column}.card-back{transform:rotateY(180deg);padding:18px;font-size:13px}
.card-idx{font-size:11px;font-weight:900;color:var(--fg3);letter-spacing:1px;text-transform:uppercase;margin-bottom:8px}.card-title{font-size:15px;font-weight:800;line-height:1.6;flex:1}.card-tag{align-self:flex-start;margin-top:12px;padding:3px 10px;border-radius:16px;background:var(--accent-soft);color:var(--accent);font-size:11px;font-weight:900}
.card-back h4{font-size:12px;font-weight:900;color:var(--accent);margin:10px 0 4px;letter-spacing:.5px;text-transform:uppercase}.card-back h4:first-child{margin-top:0}.card-back p{font-size:13px;color:var(--fg2);line-height:1.75}.code-link{font-family:var(--font-mono);font-size:12px;color:var(--fg3);word-break:break-all}
.card-actions{display:flex;gap:8px;margin-top:12px;border-top:1px solid var(--border);padding-top:10px}.card-action{padding:5px 12px;border-radius:var(--radius-sm);font-size:11px;font-weight:900;color:#fff}.card-action.practice{background:var(--success)}.card-action.review{background:var(--warn)}
.table{width:100%;border-collapse:separate;border-spacing:0;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;font-size:13.5px}.table th{background:var(--bg2);color:var(--fg3);text-align:left;padding:10px 14px;font-size:12px;text-transform:uppercase}.table td{padding:10px 14px;border-top:1px solid var(--border);color:var(--fg2)}
.search-result{padding:14px 18px;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);margin:8px 0;cursor:pointer}.search-result:hover{border-color:var(--accent);box-shadow:var(--shadow-sm)}.sr-mode{font-size:10px;font-weight:900;color:var(--accent);letter-spacing:.6px;text-transform:uppercase}.sr-title{font-size:14px;font-weight:800;color:var(--fg);margin-top:2px}.sr-snippet{font-size:13px;color:var(--fg3);line-height:1.55;margin-top:4px}mark{background:var(--accent-glow);color:var(--accent);border-radius:3px;padding:1px 3px;font-weight:800}
/* ═══════════ PREMIUM SURFACE FINAL PASS ═══════════ */
.hero,.section-card,.panel,.quiz-item,.card-face,.search-result,.mentor-card,.score-card,.lv-block,.table{background:var(--glass);border:1px solid var(--glass-border);box-shadow:var(--shadow-glass);backdrop-filter:blur(22px) saturate(1.28);-webkit-backdrop-filter:blur(22px) saturate(1.28)}
.hero:hover,.section-card:hover,.panel:hover,.search-result:hover,.mentor-card:hover{border-color:var(--glass-border);box-shadow:var(--shadow-glass),0 0 0 1px rgba(99,102,241,.10);transform:translateY(-1px)}
.source-item,pre,.framework-step,.md-pill,.pill,.sub-item.active,.side-item.active,.badge,.timer,.table th{background:rgba(255,255,255,.56);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.55) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .side-item.active,[data-theme="dark"] .badge,[data-theme="dark"] .timer,[data-theme="dark"] .table th{background:rgba(255,255,255,.07);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.table td{border-color:var(--glass-border)}
/* ═══════════ PREMIUM DEPTH SYSTEM ═══════════ */
:root{
 --layer-page:
 linear-gradient(135deg,rgba(99,102,241,.14) 0%,rgba(99,102,241,0) 34%),
 linear-gradient(225deg,rgba(20,184,166,.12) 0%,rgba(20,184,166,0) 38%),
 linear-gradient(180deg,#fbfcff 0%,#edf2f8 46%,#f8fafc 100%);
 --layer-main:linear-gradient(180deg,rgba(255,255,255,.38),rgba(255,255,255,.08));
 --glass-nav:rgba(255,255,255,.78);
 --glass-sidebar:rgba(255,255,255,.58);
 --glass-card:rgba(255,255,255,.68);
 --glass-card-strong:rgba(255,255,255,.84);
 --glass-chip:rgba(255,255,255,.50);
 --stroke-strong:rgba(255,255,255,.82);
 --shadow-nav:0 18px 55px rgba(15,23,42,.10),0 1px 0 rgba(255,255,255,.82) inset;
 --shadow-side:14px 0 44px rgba(15,23,42,.07),1px 0 0 rgba(255,255,255,.70) inset;
 --shadow-card-rich:0 22px 64px rgba(15,23,42,.12),0 8px 22px rgba(15,23,42,.06),0 1px 0 rgba(255,255,255,.80) inset;
 --shadow-card-hover-rich:0 28px 76px rgba(15,23,42,.16),0 10px 26px rgba(15,23,42,.08),0 1px 0 rgba(255,255,255,.86) inset;
 --shadow-hero-rich:0 30px 90px rgba(15,23,42,.16),0 1px 0 rgba(255,255,255,.88) inset;
}
[data-theme="dark"]{
 --layer-page:
 linear-gradient(135deg,rgba(99,102,241,.18) 0%,rgba(99,102,241,0) 34%),
 linear-gradient(225deg,rgba(20,184,166,.12) 0%,rgba(20,184,166,0) 38%),
 linear-gradient(180deg,#09090b 0%,#101216 48%,#08090b 100%);
 --layer-main:linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.01));
 --glass-nav:rgba(20,20,23,.76);
 --glass-sidebar:rgba(20,20,23,.62);
 --glass-card:rgba(24,24,27,.64);
 --glass-card-strong:rgba(32,32,36,.74);
 --glass-chip:rgba(255,255,255,.07);
 --stroke-strong:rgba(255,255,255,.13);
 --shadow-nav:0 18px 58px rgba(0,0,0,.42),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-side:14px 0 46px rgba(0,0,0,.28),1px 0 0 rgba(255,255,255,.06) inset;
 --shadow-card-rich:0 24px 68px rgba(0,0,0,.38),0 8px 22px rgba(0,0,0,.22),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-card-hover-rich:0 30px 78px rgba(0,0,0,.48),0 12px 30px rgba(0,0,0,.26),0 1px 0 rgba(255,255,255,.10) inset;
 --shadow-hero-rich:0 34px 92px rgba(0,0,0,.50),0 1px 0 rgba(255,255,255,.10) inset;
}
body{background:var(--layer-page) fixed}
.app{background:linear-gradient(90deg,rgba(255,255,255,.16),rgba(255,255,255,.02) 42%,rgba(255,255,255,.08))}
[data-theme="dark"] .app{background:linear-gradient(90deg,rgba(255,255,255,.025),rgba(255,255,255,.008) 42%,rgba(255,255,255,.018))}
.main{background:var(--layer-main)}
.topnav{background:var(--glass-nav);border-bottom:1px solid var(--stroke-strong);box-shadow:var(--shadow-nav)}
.sidebar{background:var(--glass-sidebar);border-right:1px solid var(--stroke-strong);box-shadow:var(--shadow-side)}
.mode-tabs{background:rgba(255,255,255,.42);border:1px solid var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.72) inset,0 10px 26px rgba(15,23,42,.06);padding:4px}
[data-theme="dark"] .mode-tabs{background:rgba(255,255,255,.055);box-shadow:0 1px 0 rgba(255,255,255,.08) inset,0 12px 30px rgba(0,0,0,.26)}
.mode-btn{position:relative;font-weight:800}
.mode-btn.active{background:linear-gradient(180deg,#2b2b31,#111114);box-shadow:0 12px 28px rgba(17,17,19,.24),0 1px 0 rgba(255,255,255,.22) inset}
[data-theme="dark"] .mode-btn.active{background:linear-gradient(180deg,rgba(255,255,255,.20),rgba(255,255,255,.08));box-shadow:0 12px 30px rgba(0,0,0,.36),0 1px 0 rgba(255,255,255,.14) inset}
.search-box,.repo-link,.light-link,.theme-btn,.timer{background:var(--glass-chip);border:1px solid var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.62) inset,0 10px 26px rgba(15,23,42,.05);backdrop-filter:blur(18px) saturate(1.2);-webkit-backdrop-filter:blur(18px) saturate(1.2)}
[data-theme="dark"] .search-box,[data-theme="dark"] .repo-link,[data-theme="dark"] .light-link,[data-theme="dark"] .theme-btn,[data-theme="dark"] .timer{box-shadow:0 1px 0 rgba(255,255,255,.08) inset,0 12px 30px rgba(0,0,0,.22)}
.side-title{padding:10px 12px 8px;color:var(--fg3);font-size:11px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.side-item{position:relative;min-height:36px;padding:8px 10px 8px 14px;border-radius:var(--radius-sm);font-weight:650;transition:background .18s,color .18s,box-shadow .18s,transform .18s}
.side-item::before{content:'';position:absolute;left:6px;top:9px;bottom:9px;width:2px;border-radius:2px;background:transparent;transition:background .18s,top .18s,bottom .18s}
.side-item:hover{background:rgba(255,255,255,.36);color:var(--fg);transform:translateX(1px)}
[data-theme="dark"] .side-item:hover{background:rgba(255,255,255,.055)}
.side-item.active{background:rgba(255,255,255,.62);color:var(--accent);font-weight:850;box-shadow:0 10px 24px rgba(99,102,241,.10),0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .side-item.active{background:rgba(255,255,255,.08);box-shadow:0 12px 28px rgba(0,0,0,.24),0 1px 0 rgba(255,255,255,.08) inset}
.side-item.active::before{top:7px;bottom:7px;background:linear-gradient(180deg,var(--accent),var(--accent2))}
.badge{background:rgba(24,24,27,.06);color:var(--fg3);border:1px solid rgba(24,24,27,.06)}
[data-theme="dark"] .badge{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.08)}
.side-item.active .badge{background:linear-gradient(180deg,var(--accent),var(--accent2));color:#fff;border-color:transparent;box-shadow:0 6px 16px var(--accent-glow)}
.markdown-doc{background:var(--glass-card-strong);border:1px solid var(--stroke-strong);border-radius:var(--radius);box-shadow:var(--shadow-hero-rich);padding:36px 42px;position:relative;overflow:hidden;backdrop-filter:blur(26px) saturate(1.24);-webkit-backdrop-filter:blur(26px) saturate(1.24)}
.markdown-doc::before{content:'';position:absolute;inset:0 0 auto;height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.92),transparent)}
[data-theme="dark"] .markdown-doc::before{background:linear-gradient(90deg,transparent,rgba(255,255,255,.14),transparent)}
.markdown-doc h1{font-size:32px;letter-spacing:0}
.markdown-doc h2{border-top-color:rgba(24,24,27,.09)}
[data-theme="dark"] .markdown-doc h2{border-top-color:rgba(255,255,255,.09)}
.md-section{padding:2px 0 12px;border-radius:var(--radius-sm);transition:background .22s,padding .22s,margin .22s,box-shadow .22s}
.md-section.active{background:linear-gradient(90deg,rgba(99,102,241,.13),rgba(20,184,166,.07),transparent 78%);padding-left:16px;margin-left:-16px;box-shadow:inset 3px 0 0 var(--accent)}
[data-theme="dark"] .md-section.active{background:linear-gradient(90deg,rgba(129,140,248,.16),rgba(20,184,166,.07),transparent 78%)}
.hero{background:var(--glass-card-strong);border-color:var(--stroke-strong);box-shadow:var(--shadow-hero-rich)}
.section-card,.panel,.quiz-item,.card-face,.search-result,.mentor-card,.score-card,.lv-block,.table{background:var(--glass-card);border-color:var(--stroke-strong);box-shadow:var(--shadow-card-rich)}
.hero:hover,.section-card:hover,.panel:hover,.quiz-item:hover,.search-result:hover,.mentor-card:hover{border-color:rgba(99,102,241,.28);box-shadow:var(--shadow-card-hover-rich);transform:translateY(-2px)}
.source-item,pre,.framework-step,.md-pill,.pill,.sub-item.active,.badge,.timer,.table th{background:var(--glass-chip);border-color:var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .badge,[data-theme="dark"] .timer,[data-theme="dark"] .table th{background:var(--glass-chip);border-color:var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.nav-btn,.tool-btn{box-shadow:0 10px 24px rgba(15,23,42,.08),0 1px 0 rgba(255,255,255,.55) inset}
.nav-btn.primary,.tool-btn.primary{box-shadow:0 14px 30px var(--accent-glow),0 1px 0 rgba(255,255,255,.24) inset}
/* Keep blur on small, stationary chrome only. Large surfaces inside the
 scrolling pane otherwise force expensive backdrop repaints while scrolling. */
.main .markdown-doc,.main .section-card,.main .panel,.main .hero,.main .quiz-item,.main .card-face,.main .search-result,.main .mentor-card,.main .score-card,.main .lv-block,.main .table,.main blockquote{
 backdrop-filter:none;
 -webkit-backdrop-filter:none;
}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
@media(max-width:1080px){.light-link{display:none}.search-box{width:170px}.search-box:focus{width:220px}.main{padding:24px}.card-grid{grid-template-columns:1fr}}
@media(max-width:720px){
 body::before{display:none}
 .topnav{height:auto;min-height:var(--topnav-h);padding:10px 12px;flex-direction:column;align-items:stretch}.brand{width:100%;margin-right:0}.brand-sub{display:none}.mode-tabs{flex-direction:column}.mode-btn{width:100%;padding:8px 10px}.repo-link,.light-link{display:flex;justify-content:center}.search-box,.search-box:focus{width:100%}.app{display:block;height:auto;min-height:calc(100dvh - 180px)}.sidebar{display:none}.main{padding:16px 14px 48px}.hero,.section-card,.panel{padding:18px 16px}.hero h2{font-size:23px}.content-header h1{font-size:22px}.grid{grid-template-columns:1fr}.nav-bar{flex-direction:column}.nav-btn{width:100%}.card{height:380px}.quiz-q{padding:12px}.quiz-btns{flex-direction:column}.quiz-btn{width:100%;padding:8px 12px}.table{display:block;overflow:auto;white-space:nowrap}
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="topnav"&gt;
 &lt;div class="brand"&gt;
 &lt;div class="brand-icon" aria-label="Go Gopher"&gt;
 &lt;svg viewBox="0 0 64 64" role="img" aria-hidden="true"&gt;
 &lt;ellipse cx="18" cy="24" rx="9" ry="11" fill="#6fd4e6"/&gt;&lt;ellipse cx="46" cy="24" rx="9" ry="11" fill="#6fd4e6"/&gt;&lt;ellipse cx="32" cy="35" rx="24" ry="20" fill="#74d7e8"/&gt;
 &lt;ellipse cx="23" cy="32" rx="4" ry="5" fill="#111827"/&gt;&lt;ellipse cx="41" cy="32" rx="4" ry="5" fill="#111827"/&gt;&lt;ellipse cx="32" cy="39" rx="6" ry="4" fill="#27252a"/&gt;
 &lt;rect x="27" y="45" width="10" height="7" rx="2" fill="#fff"/&gt;&lt;path d="M32 43v10" stroke="#27252a" stroke-width="2" stroke-linecap="round"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div&gt;&lt;span class="brand-text"&gt;视频Feed流系统&lt;/span&gt;&lt;span class="brand-sub"&gt;（hard）学习&lt;/span&gt;&lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="mode-tabs"&gt;
 &lt;button class="mode-btn active" data-mode="intro" onclick="switchMode('intro')"&gt;前言&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="learn" onclick="switchMode('learn')"&gt;知识学习&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="breakdown" onclick="switchMode('breakdown')"&gt;项目拆解&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="interview" onclick="switchMode('interview')"&gt;面试模拟&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="scenario" onclick="switchMode('scenario')"&gt;场景还原&lt;/button&gt;
 &lt;/div&gt;
 &lt;a class="repo-link" href="https://github.com/LeoninCS/GCFeed" target="_blank" rel="noopener"&gt;GitHub 仓库&lt;/a&gt;
 &lt;a class="light-link" href="https://go.botsarena.tech/docs/project-study/study-feed/"&gt;medium 版&lt;/a&gt;
 &lt;div class="search-wrap"&gt;&lt;span class="search-icon"&gt;⌕&lt;/span&gt;&lt;input id="searchInput" class="search-box" type="text" placeholder="搜索内容..." oninput="handleSearch(this.value)"&gt;&lt;/div&gt;
 &lt;button class="theme-btn" onclick="toggleTheme()" title="切换主题"&gt;&lt;span id="themeIcon"&gt;☽&lt;/span&gt;&lt;/button&gt;
 &lt;div class="progress-pill"&gt;&lt;span class="dot"&gt;&lt;/span&gt;&lt;span id="progressText"&gt;0/15&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="app" id="app"&gt;&lt;/div&gt;
&lt;script&gt;
const introData={
 title:"视频Feed流系统（hard）15天项目学习",
 desc:"视频Feed流系统（hard）基于 GCFeed 仓库，是一个更完整的短视频 Feed 工程：后端采用 Domain、Application、Infrastructure、Interfaces 四层结构，覆盖账户、视频、Feed、互动、关系、推荐、曝光、Embedding、Web 客户端和测试。hard 版学习目标是把“能跑的项目”拆成可讲、可改、可面试的工程闭环。",
 repo:"https://github.com/LeoninCS/GCFeed",
 pillars:[
 {title:"项目介绍",text:"这是一个短视频 Feed 流 hard 版项目学习页，基于 LeoninCS/GCFeed 仓库整理。项目覆盖账户、视频发布、timeline、hot、following、recommend、互动、曝光、Embedding、Web 客户端和测试，适合把 Feed 系统从能运行一路学到能面试。"},
 {title:"前置要求",text:"建议先具备 Go 基础、Gin/GORM、MySQL、Redis、RabbitMQ、HTTP API、JWT、React/Vite、Docker Compose、基础系统设计知识。掌握这些后，阅读源码、理解链路和回答追问会顺很多。"},
 {title:"Level 1：能跑能演示",text:"这一层代表入门完成度：能启动项目，能演示注册、登录、发布视频、刷 Feed、点赞评论、关注、推荐曝光，知道每个功能解决什么业务问题。"},
 {title:"Level 2：面试级理解",text:"这一层代表面试主线完成度：能讲清四层架构、模块边界、核心链路和常见面试问题，能用 2 分钟把项目讲成一个完整工程故事。"},
 {title:"Level 3：抗追问能力",text:"这一层代表二三轮追问完成度：对缓存击穿、MQ 故障、幂等、游标分页、推拉结合、曝光去重、推荐降级等场景有判断和方案。"},
 {title:"Level 4：可独立复刻",text:"这一层代表源码内化完成度：脑子里有目录结构、接口链路、数据表和关键代码形态，可以从零复刻一个可运行版本。"},
 {title:"Level 5：Feed 流之神",text:"这一层代表抽象能力完成度：能把项目升维成通用 Feed 系统方法论，能主动讨论设计边界、容量估算、排序策略和工程演进。"},
 {title:"学习方法",text:"你可以先看我的文档建立路线，再跟着页面每天学习；也可以让页面引导你走完目标、源码入口、核心问题、自检题、面试打法。每天只吃透一个主题。"},
 {title:"最终产出",text:"学完后要有 2 分钟项目介绍、4 条核心链路图、8 个简历亮点、40+ 道面试问答、故障场景清单、扩展设计方案和一套可复盘的源码笔记。"},
 {title:"Offer 冲刺",text:"这页的目标是帮你把项目讲得清楚、答得有证据、追问接得住。认真走完 15 天，你应该能把 Feed 项目变成大厂面试里的强项目。"}
 ],
 prerequisites:["Go 基础与并发模型","Gin / GORM / RESTful API","MySQL 表设计、事务、索引","Redis 缓存、ZSET、Lua、限流","RabbitMQ 消息投递、Ack、异步消费","JWT 鉴权与中间件","React / Vite 基础页面联调","Docker Compose 本地环境","缓存、MQ、一致性、Feed 流系统设计"],
 levels:[
 {title:"Level 1：能跑能演示",text:"学到可以完整演示功能，并能说明每个功能对应的业务价值。"},
 {title:"Level 2：面试级理解",text:"学到可以讲清架构、链路、源码入口和常见面试题。"},
 {title:"Level 3：抗追问能力",text:"学到可以处理特殊场景追问，并能给出工程权衡。"},
 {title:"Level 4：可独立复刻",text:"学到可以关掉文档复刻核心模块，脑子里有代码结构。"},
 {title:"Level 5：Feed 流之神",text:"学到可以抽象出 Feed 系统方法论，现场讨论边界、容量和演进。"}
 ],
 levelStandards:[
 {standard:"能从本地启动到页面体验完整跑一遍。",proof:"能画出用户使用闭环：注册登录 -&gt; 发布视频 -&gt; Feed 分发 -&gt; 互动 -&gt; 曝光反馈。",next:"进入架构和源码入口学习。"},
 {standard:"能用架构图讲清 Domain、Application、Infrastructure、Interfaces。",proof:"能用发布、刷 Feed、互动、推荐曝光四条链路回答主干面试题。",next:"开始准备故障、并发、一致性和降级追问。"},
 {standard:"能解释缓存、MQ、幂等、游标、推拉、推荐、曝光的特殊场景。",proof:"面试官连续追问时，回答能回到源码证据和工程权衡。",next:"把代码结构背到可以复刻。"},
 {standard:"能从零写出最小可运行版本。",proof:"能还原目录结构、接口设计、核心表、Service 编排和缓存/MQ 关键代码。",next:"把项目抽象成通用 Feed 系统设计框架。"},
 {standard:"能从项目上升到系统设计方法论。",proof:"能主动讨论召回、排序、分发、曝光、容量、治理、灰度和演进路线。",next:"把它变成大厂面试的压轴项目。"}
 ],
 studyPath:[
 {title:"看文档建地图",text:"先读项目 README、quickread、architecture，再看本页前言，建立系统地图。"},
 {title:"跟 15 天走源码",text:"每天按目标、源码入口、核心知识点、自检题、面试打法推进。"},
 {title:"把问题答成结构",text:"每道题都用结论、场景、源码、机制、权衡、扩展组织语言。"},
 {title:"用输出倒逼学习",text:"每天沉淀一句介绍、一个链路图、一个源码证据、一个追问答案。"}
 ],
 outputs:["15 天源码阅读笔记","4 条主链路图：发布、刷 Feed、互动、推荐曝光","一份 2 分钟项目介绍稿","8 个技术亮点与源码依据","40+ 道 hard 版面试问答","故障场景与扩展方案清单"],
 method:[
 {title:"先运行",text:"先让项目跑起来，功能体验会给源码阅读提供坐标。"},
 {title:"再分层",text:"从 router.Register 看依赖装配，再进入 Domain、Application、Infrastructure、Interfaces。"},
 {title:"追链路",text:"用发布、刷 Feed、互动、推荐曝光四条主链路串起代码。"},
 {title:"背表达",text:"把每个技术点整理成面试答案，并绑定源码文件。"},
 {title:"抗追问",text:"用故障、并发、容量、降级、扩展场景训练二三轮追问。"},
 {title:"拿 Offer",text:"把项目讲成可信工程经历，让它成为冲大厂的核心项目。"}
 ],
 answerFrame:["一句话结论","业务场景","源码证据","核心机制","权衡风险","生产扩展"],
 scorecard:[
 {title:"结构清晰",text:"回答有起点、链路、结果，面试官能快速跟上。"},
 {title:"源码可信",text:"关键说法都能指到文件、函数和数据结构。"},
 {title:"理论扎实",text:"能解释一致性、复杂度、缓存、MQ、事务的取舍。"},
 {title:"可扩展",text:"能给出生产化演进方案和故障处理方案。"}
 ]
};

const learnData=[
{title:"第1章：系统边界与四层架构",topics:[
{q:"hard 版 Feed 系统的核心边界是什么？",lv1:`&lt;p&gt;它覆盖内容供给、分发、消费、互动反馈和推荐曝光。用户发布视频后，内容进入 timeline、following、hot、recommend 等场景；用户浏览和互动后，系统记录曝光、计数和兴趣反馈。&lt;/p&gt;</description></item><item><title>视频Feed流系统（medium）学习</title><link>https://go.botsarena.tech/docs/project-study/study-feed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://go.botsarena.tech/docs/project-study/study-feed/</guid><description>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN" data-theme="light"&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
&lt;title&gt;视频Feed流系统（medium）学习&lt;/title&gt;
&lt;link rel="icon" type="image/svg+xml" href='data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"%3E%3Crect width="64" height="64" rx="16" fill="%23e0f7fa"/%3E%3Cellipse cx="18" cy="24" rx="9" ry="11" fill="%2370d7e7"/%3E%3Cellipse cx="46" cy="24" rx="9" ry="11" fill="%2370d7e7"/%3E%3Cellipse cx="32" cy="35" rx="24" ry="20" fill="%236fd4e6"/%3E%3Cellipse cx="23" cy="32" rx="4" ry="5" fill="%23111827"/%3E%3Cellipse cx="41" cy="32" rx="4" ry="5" fill="%23111827"/%3E%3Cellipse cx="32" cy="39" rx="6" ry="4" fill="%2327252a"/%3E%3Crect x="27" y="45" width="10" height="7" rx="2" fill="white"/%3E%3Cpath d="M32 43v10" stroke="%2327252a" stroke-width="2" stroke-linecap="round"/%3E%3Cpath d="M13 39c-4 1-7 3-9 6M51 39c4 1 7 3 9 6" stroke="%2327252a" stroke-width="3" stroke-linecap="round"/%3E%3C/svg%3E'&gt;
&lt;style&gt;
/* ═══════════ DESIGN TOKENS ═══════════ */
:root {
 --bg: #fafafa; --bg2: #f0f0f0; --bg3: #e4e4e7; --fg: #18181b; --fg2: #71717a; --fg3: #a1a1aa;
 --accent: #6366f1; --accent2: #4f46e5; --accent-soft: #eef2ff; --accent-glow: rgba(99,102,241,.15);
 --border: #e4e4e7; --card: #ffffff; --card-hover: #fafafa;
 --code-bg: #f4f4f5; --code-border: #e4e4e7;
 --shadow-sm: 0 1px 2px rgba(0,0,0,.05); --shadow-md: 0 4px 12px rgba(0,0,0,.08); --shadow-lg: 0 8px 30px rgba(0,0,0,.12);
 --success: #22c55e; --success-soft: #f0fdf4; --warn: #f59e0b; --warn-soft: #fffbeb; --danger: #ef4444; --danger-soft: #fef2f2;
 --info: #3b82f6; --info-soft: #eff6ff;
 --sidebar-w: 280px; --topnav-h: 56px; --radius: 10px; --radius-sm: 6px;
 --tag-bg: #eef2ff; --tag-fg: #4338ca;
 --font-body: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
 --font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace;
 --noise: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.03'/%3E%3C/svg%3E");
 --lv1: #22c55e; --lv1-soft: #f0fdf4; --lv1-border: rgba(34,197,94,.3);
 --lv2: #3b82f6; --lv2-soft: #eff6ff; --lv2-border: rgba(59,130,246,.3);
 --lv3: #f59e0b; --lv3-soft: #fffbeb; --lv3-border: rgba(245,158,11,.3);
}
[data-theme="dark"] {
 --bg: #09090b; --bg2: #18181b; --bg3: #27272a; --fg: #fafafa; --fg2: #a1a1aa; --fg3: #71717a;
 --accent: #818cf8; --accent2: #6366f1; --accent-soft: #1e1b4b; --accent-glow: rgba(129,140,248,.12);
 --border: #27272a; --card: #18181b; --card-hover: #1f1f23;
 --code-bg: #1e1e22; --code-border: #2e2e33;
 --shadow-sm: 0 1px 2px rgba(0,0,0,.3); --shadow-md: 0 4px 12px rgba(0,0,0,.4); --shadow-lg: 0 8px 30px rgba(0,0,0,.5);
 --success-soft: #052e16; --warn-soft: #451a03; --danger-soft: #450a0a; --info-soft: #172554;
 --tag-bg: #1e1b4b; --tag-fg: #c7d2fe;
 --lv1-soft: #052e16; --lv2-soft: #172554; --lv3-soft: #451a03;
}
/* ═══════════ RESET ═══════════ */
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-font-smoothing:antialiased}
body{font-family:var(--font-body);background:var(--bg);color:var(--fg);line-height:1.7;font-size:15px;transition:background .4s,color .4s;min-height:100vh}
body::before{content:'';position:fixed;inset:0;background:var(--noise);pointer-events:none;z-index:9999;opacity:.4}
a{color:var(--accent);text-decoration:none}
button{cursor:pointer;border:none;font-family:inherit;font-size:inherit;background:none}
::selection{background:var(--accent);color:#fff}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--fg3);border-radius:10px}
/* ═══════════ TOPNAV ═══════════ */
.topnav{display:flex;align-items:center;gap:10px;padding:0 20px;background:var(--card);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100;height:var(--topnav-h);backdrop-filter:blur(12px)}
.topnav::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.3}
.brand{display:flex;align-items:center;gap:10px;margin-right:auto;white-space:nowrap}
.brand-icon{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;background:#e0f7fa;box-shadow:0 2px 8px var(--accent-glow);overflow:hidden;border:1px solid rgba(15,118,140,.16);flex-shrink:0}
.brand-icon svg{display:block;width:30px;height:30px}
.brand-text{font-size:15px;font-weight:700;letter-spacing:-.3px}
.brand-sub{font-size:11px;color:var(--fg3);margin-left:4px}
.mode-tabs{display:flex;background:var(--bg2);border-radius:8px;padding:3px;gap:2px}
.mode-btn{padding:5px 14px;border-radius:6px;font-size:13px;font-weight:500;color:var(--fg2);transition:all .25s}
.mode-btn.active{background:var(--accent);color:#fff;box-shadow:0 2px 8px var(--accent-glow)}
.mode-btn:not(.active):hover{color:var(--fg);background:var(--bg3)}
.search-wrap{position:relative}
.search-box{padding:6px 12px 6px 32px;border:1px solid var(--border);border-radius:8px;background:var(--bg2);color:var(--fg);width:220px;font-size:13px;font-family:var(--font-body);transition:all .25s;outline:none}
.search-box:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow);width:280px}
.search-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--fg3);font-size:13px;pointer-events:none}
.theme-btn{width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:var(--fg2);transition:all .25s;font-size:16px}
.theme-btn:hover{background:var(--bg2);color:var(--fg);transform:rotate(15deg)}
.repo-link{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid var(--border);border-radius:8px;background:var(--bg2);color:var(--fg2);font-size:13px;font-weight:500;line-height:1;transition:all .25s;white-space:nowrap}
.repo-link:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft);box-shadow:0 2px 8px var(--accent-glow)}
.progress-pill{display:flex;align-items:center;gap:6px;padding:4px 12px;background:var(--success-soft);border-radius:20px;font-size:12px;font-weight:500;color:var(--success);border:1px solid rgba(34,197,94,.2)}
.progress-pill .dot{width:6px;height:6px;border-radius:50%;background:var(--success);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}
/* ═══════════ LAYOUT ═══════════ */
.app{display:flex;height:calc(100vh - var(--topnav-h));overflow:hidden}
/* ═══════════ SIDEBAR ═══════════ */
.sidebar{width:var(--sidebar-w);min-width:var(--sidebar-w);background:var(--card);border-right:1px solid var(--border);overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:2px}
.sidebar::-webkit-scrollbar{width:3px}
.ch-group{border-radius:var(--radius-sm);overflow:hidden}
.ch-header{display:flex;align-items:center;gap:8px;padding:8px 10px;cursor:pointer;border-radius:var(--radius-sm);transition:all .2s;font-size:13.5px;font-weight:500;color:var(--fg2);user-select:none}
.ch-header:hover{background:var(--bg2);color:var(--fg)}
.ch-header.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
.ch-arrow{font-size:10px;transition:transform .25s;color:var(--fg3);flex-shrink:0}
.ch-header.active .ch-arrow,.ch-header.open .ch-arrow{transform:rotate(90deg)}
.ch-title{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ch-badge{font-size:10px;padding:1px 6px;border-radius:10px;background:var(--bg3);color:var(--fg3);flex-shrink:0;font-weight:500}
.ch-header.active .ch-badge{background:var(--accent);color:#fff}
.ch-bar{height:3px;background:var(--bg3);border-radius:2px;margin:0 10px 4px;overflow:hidden;opacity:0;transition:opacity .2s}
.ch-header.active+.ch-bar,.ch-header.open+.ch-bar{opacity:1}
.ch-bar-fill{height:100%;background:linear-gradient(90deg,var(--success),#4ade80);border-radius:2px;transition:width .5s cubic-bezier(.4,0,.2,1)}
.ch-subs{max-height:0;overflow:hidden;transition:max-height .3s cubic-bezier(.4,0,.2,1);padding-left:8px}
.ch-subs.open{max-height:800px}
.sub-item{font-size:12.5px;padding:5px 10px;cursor:pointer;border-radius:var(--radius-sm);color:var(--fg3);transition:all .15s;margin:1px 0;position:relative}
.sub-item::before{content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);width:2px;height:0;background:var(--accent);border-radius:1px;transition:height .2s}
.sub-item:hover{color:var(--fg);background:var(--bg2)}
.sub-item.active{color:var(--accent);font-weight:500;background:var(--accent-soft)}
.sub-item.active::before{height:60%}
.dim-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;cursor:pointer;border-radius:var(--radius-sm);font-size:13px;color:var(--fg2);transition:all .2s}
.dim-item:hover{background:var(--bg2);color:var(--fg)}
.dim-item.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
.dim-badge{font-size:10px;padding:1px 6px;border-radius:10px;background:var(--bg3);color:var(--fg3)}
.dim-item.active .dim-badge{background:var(--accent);color:#fff}
/* ═══════════ MAIN CONTENT ═══════════ */
.main{flex:1;overflow-y:auto;padding:32px 40px 60px;scroll-behavior:smooth}
.main::-webkit-scrollbar{width:4px}
.content-header{margin-bottom:28px;animation:fadeUp .4s ease}
.content-header h1{font-size:26px;font-weight:900;letter-spacing:-.5px;background:linear-gradient(135deg,var(--fg) 60%,var(--accent));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;line-height:1.3}
.content-header .subtitle{font-size:13px;color:var(--fg3);margin-top:4px}
.section-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:28px 32px;margin-bottom:20px;box-shadow:var(--shadow-sm);transition:all .25s;animation:fadeUp .4s ease}
.section-card:hover{box-shadow:var(--shadow-md);border-color:var(--accent-glow)}
.section-card h2{font-size:18px;font-weight:700;margin-bottom:16px;color:var(--fg);display:flex;align-items:center;gap:8px}
.section-card h2::before{content:'';width:3px;height:20px;background:linear-gradient(180deg,var(--accent),var(--accent2));border-radius:2px;flex-shrink:0}
.section-card p{margin:10px 0;color:var(--fg2);font-size:14.5px;line-height:1.8}
.section-card ul,.section-card ol{margin:10px 0 10px 20px;color:var(--fg2);font-size:14.5px}
.section-card li{margin:6px 0;line-height:1.7}
.section-card li strong{color:var(--fg);font-weight:600}
.section-card code.inline{background:var(--code-bg);padding:2px 7px;border-radius:4px;font-size:13px;font-family:var(--font-mono);color:var(--accent);border:1px solid var(--code-border)}
@keyframes fadeUp{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}
pre{background:var(--code-bg);border:1px solid var(--code-border);border-radius:var(--radius);padding:18px 20px;overflow-x:auto;margin:16px 0;font-size:13px;line-height:1.65;position:relative;font-family:var(--font-mono)}
pre::before{content:'Go';position:absolute;top:8px;right:12px;font-size:10px;color:var(--fg3);font-weight:500;letter-spacing:1px;text-transform:uppercase;opacity:.5}
pre code{font-family:var(--font-mono);color:var(--fg)}
.kw{color:#d73a49;font-weight:500}.cm{color:#6a9955;font-style:italic}.str{color:#032f62}.fn{color:#6f42c1}.num{color:#005cc5}
[data-theme="dark"] .kw{color:#ff7b72}[data-theme="dark"] .cm{color:#7ee787}[data-theme="dark"] .str{color:#a5d6ff}[data-theme="dark"] .fn{color:#d2a8ff}[data-theme="dark"] .num{color:#79c0ff}
/* ═══════════ LV1/LV2/LV3 ACCORDION ═══════════ */
.lv-block{margin:12px 0;border-radius:var(--radius-sm);overflow:hidden;border:1px solid var(--border);transition:border-color .2s}
.lv-block.lv1{border-left:3px solid var(--lv1)}
.lv-block.lv2{border-left:3px solid var(--lv2)}
.lv-block.lv3{border-left:3px solid var(--lv3)}
.lv-header{display:flex;align-items:center;gap:8px;padding:12px 16px;cursor:pointer;font-size:14px;font-weight:600;transition:background .15s;user-select:none}
.lv-block.lv1 .lv-header{color:var(--lv1);background:var(--lv1-soft)}
.lv-block.lv2 .lv-header{color:var(--lv2);background:var(--lv2-soft)}
.lv-block.lv3 .lv-header{color:var(--lv3);background:var(--lv3-soft)}
.lv-header:hover{filter:brightness(.95)}
.lv-arrow{font-size:10px;transition:transform .25s;color:var(--fg3);flex-shrink:0}
.lv-header.open .lv-arrow{transform:rotate(90deg)}
.lv-tag{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;flex-shrink:0}
.lv-block.lv1 .lv-tag{background:var(--lv1);color:#fff}
.lv-block.lv2 .lv-tag{background:var(--lv2);color:#fff}
.lv-block.lv3 .lv-tag{background:var(--lv3);color:#fff}
.lv-body{max-height:0;overflow:hidden;transition:max-height .4s cubic-bezier(.4,0,.2,1);padding:0 16px}
.lv-body.open{max-height:3000px;padding:0 16px 16px}
.lv-body p{margin:8px 0;color:var(--fg2);font-size:14px;line-height:1.8}
.lv-body ul,.lv-body ol{margin:8px 0 8px 20px;color:var(--fg2);font-size:14px}
.lv-body li{margin:4px 0;line-height:1.7}
.lv-body strong{color:var(--fg);font-weight:600}
.lv-body code.inline{background:var(--code-bg);padding:2px 6px;border-radius:4px;font-size:12.5px;font-family:var(--font-mono);color:var(--accent);border:1px solid var(--code-border)}
.lv-body pre{font-size:12.5px;padding:14px 16px;margin:12px 0}
.lv-why{margin:10px 0;padding:10px 14px;background:var(--warn-soft);border-radius:var(--radius-sm);font-size:13px;color:var(--fg2);border-left:3px solid var(--warn)}
.lv-why::before{content:'💡 ';font-weight:700}
/* ═══════════ QUIZ ═══════════ */
.quiz-section{margin-top:8px}
.quiz-section h2{font-size:20px;font-weight:800;margin-bottom:16px;display:flex;align-items:center;gap:8px}
.quiz-section h2::before{content:'';width:3px;height:20px;background:linear-gradient(180deg,var(--warn),#f59e0b);border-radius:2px}
.quiz-item{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);margin:10px 0;overflow:hidden;transition:all .25s;animation:fadeUp .3s ease}
.quiz-item:hover{border-color:var(--accent-glow);box-shadow:var(--shadow-sm)}
.quiz-q{padding:14px 18px;cursor:pointer;display:flex;align-items:flex-start;gap:10px;font-size:14px;font-weight:500;line-height:1.6;transition:background .15s}
.quiz-q:hover{background:var(--bg2)}
.quiz-q .q-num{flex-shrink:0;width:24px;height:24px;border-radius:6px;background:var(--accent-soft);color:var(--accent);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;margin-top:1px}
.quiz-q .q-text{flex:1}
.quiz-q .q-toggle{flex-shrink:0;font-size:10px;color:var(--fg3);transition:transform .25s;margin-top:6px}
.quiz-q .q-toggle.open{transform:rotate(90deg)}
.quiz-status{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:600;flex-shrink:0;margin-top:3px}
.status-mastered{background:var(--success-soft);color:var(--success);border:1px solid rgba(34,197,94,.2)}
.status-unmastered{background:var(--danger-soft);color:var(--danger);border:1px solid rgba(239,68,68,.2)}
.quiz-body{max-height:0;overflow:hidden;transition:max-height .35s cubic-bezier(.4,0,.2,1)}
.quiz-body.open{max-height:800px}
.quiz-hint{margin:0 18px 14px;padding:14px 16px;background:var(--warn-soft);border-radius:var(--radius-sm);font-size:13.5px;line-height:1.7;color:var(--fg2);border-left:3px solid var(--warn)}
.quiz-btns{display:flex;gap:8px;margin:0 18px 14px}
.quiz-btn{padding:5px 14px;border-radius:var(--radius-sm);font-size:12px;font-weight:600;transition:all .2s}
.quiz-btn.mastered{background:var(--success);color:#fff;box-shadow:0 2px 6px rgba(34,197,94,.2)}
.quiz-btn.mastered:hover{background:#16a34a;transform:translateY(-1px)}
.quiz-btn.unmastered{background:var(--danger);color:#fff;box-shadow:0 2px 6px rgba(239,68,68,.2)}
.quiz-btn.unmastered:hover{background:#dc2626;transform:translateY(-1px)}
/* ═══════════ INTERVIEW CARDS ═══════════ */
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(380px,1fr));gap:16px}
.card{perspective:1200px;height:320px;cursor:pointer;animation:fadeUp .4s ease}
.card-inner{position:relative;width:100%;height:100%;transition:transform .6s cubic-bezier(.4,0,.2,1);transform-style:preserve-3d}
.card.flipped .card-inner{transform:rotateY(180deg)}
.card-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);overflow-y:auto;transition:border-color .2s,box-shadow .2s}
.card-face::-webkit-scrollbar{width:3px}
.card:hover .card-face{border-color:var(--accent-glow);box-shadow:var(--shadow-md)}
.card-front{display:flex;flex-direction:column;padding:20px}
.card-idx{font-size:11px;font-weight:700;color:var(--fg3);letter-spacing:1px;text-transform:uppercase;margin-bottom:8px}
.card-title{font-size:15px;font-weight:600;line-height:1.6;flex:1;color:var(--fg)}
.card-footer{display:flex;align-items:center;justify-content:space-between;margin-top:12px;gap:8px}
.card-tag{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:20px;background:var(--tag-bg);color:var(--tag-fg);font-size:11px;font-weight:600}
.card-status{font-size:11px;font-weight:600;padding:2px 8px;border-radius:10px}
.card-back{transform:rotateY(180deg);padding:18px;font-size:13px;line-height:1.7}
.card-back h4{font-size:12px;font-weight:700;color:var(--accent);margin:10px 0 4px;text-transform:uppercase;letter-spacing:.5px}
.card-back h4:first-child{margin-top:0}
.card-back p{color:var(--fg2);font-size:13px;line-height:1.7}
.card-back .code-link{font-size:12px;color:var(--fg3);font-family:var(--font-mono);font-style:normal;word-break:break-all}
.card-back .follow-q{color:var(--warn);font-size:12.5px}
.card-back pre{font-size:11.5px;padding:10px 12px;margin:6px 0}
.card-actions{display:flex;gap:6px;margin-top:auto;padding-top:10px;border-top:1px solid var(--border)}
.card-action{padding:4px 12px;border-radius:var(--radius-sm);font-size:11px;font-weight:600;transition:all .2s}
.card-action.practice{background:var(--success);color:#fff}
.card-action.review{background:var(--warn);color:#fff}
.card-action:hover{transform:translateY(-1px);filter:brightness(1.1)}
/* ═══════════ SCENARIO CARDS ═══════════ */
.scenario-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(400px,1fr));gap:16px}
.scenario-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:24px;transition:all .25s;animation:fadeUp .4s ease;cursor:pointer}
.scenario-card:hover{box-shadow:var(--shadow-md);border-color:var(--accent-glow)}
.scenario-card h3{font-size:16px;font-weight:700;margin-bottom:12px;color:var(--fg);display:flex;align-items:center;gap:8px}
.scenario-card h3 .sc-icon{width:28px;height:28px;border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0}
.scenario-card.e2e h3 .sc-icon{background:var(--info-soft);color:var(--info)}
.scenario-card.fault h3 .sc-icon{background:var(--danger-soft);color:var(--danger)}
.scenario-card .sc-desc{font-size:13.5px;color:var(--fg2);margin-bottom:12px;line-height:1.6}
.scenario-card .sc-steps{display:none;margin-top:12px}
.scenario-card.open .sc-steps{display:block}
.sc-step{display:flex;gap:12px;margin:8px 0;position:relative}
.sc-step::before{content:'';position:absolute;left:13px;top:28px;bottom:-8px;width:2px;background:var(--border)}
.sc-step:last-child::before{display:none}
.sc-num{width:28px;height:28px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;flex-shrink:0}
.sc-step-content{flex:1}
.sc-step-content .sc-loc{font-size:11px;color:var(--fg3);font-family:var(--font-mono);margin-top:2px}
.sc-step-content p{font-size:13.5px;color:var(--fg2);line-height:1.6}
.fault-tree{margin:8px 0;padding:12px 16px;background:var(--danger-soft);border-radius:var(--radius-sm);border-left:3px solid var(--danger)}
.fault-tree .ft-title{font-size:13px;font-weight:700;color:var(--danger);margin-bottom:6px}
.fault-tree p{font-size:13px;color:var(--fg2);line-height:1.6}
.fix-box{margin:8px 0;padding:12px 16px;background:var(--success-soft);border-radius:var(--radius-sm);border-left:3px solid var(--success)}
.fix-box .fx-title{font-size:13px;font-weight:700;color:var(--success);margin-bottom:6px}
.fix-box p{font-size:13px;color:var(--fg2);line-height:1.6}
/* ═══════════ PROJECT BREAKDOWN ═══════════ */
.breakdown-hero{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:28px 32px;margin-bottom:20px;box-shadow:var(--shadow-sm);animation:fadeUp .4s ease}
.breakdown-kicker{font-size:11px;font-weight:800;color:var(--accent);letter-spacing:.8px;text-transform:uppercase;margin-bottom:8px}
.breakdown-hero h2{font-size:24px;font-weight:900;line-height:1.35;margin-bottom:10px;color:var(--fg)}
.breakdown-hero p{font-size:14.5px;color:var(--fg2);line-height:1.8;max-width:860px}
.breakdown-meta{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.breakdown-pill{padding:4px 10px;border-radius:20px;background:var(--accent-soft);color:var(--accent);font-size:12px;font-weight:700;border:1px solid var(--accent-glow)}
.day-layout{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(300px,.75fr);gap:16px;margin-bottom:20px}
.day-panel{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:22px 24px;box-shadow:var(--shadow-sm);animation:fadeUp .4s ease}
.day-panel h3{font-size:16px;font-weight:800;margin-bottom:12px;color:var(--fg);display:flex;align-items:center;gap:8px}
.day-panel h3::before{content:'';width:3px;height:18px;background:linear-gradient(180deg,var(--accent),var(--accent2));border-radius:2px;flex-shrink:0}
.day-panel p{font-size:14px;color:var(--fg2);line-height:1.8;margin:8px 0}
.day-panel ul,.day-panel ol{margin:8px 0 8px 20px;color:var(--fg2);font-size:14px}
.day-panel li{margin:6px 0;line-height:1.7}
.source-list{display:flex;flex-direction:column;gap:8px}
.source-item{padding:9px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg2);font-family:var(--font-mono);font-size:12px;color:var(--fg2);line-height:1.45;word-break:break-all}
.checkline{display:flex;align-items:flex-start;gap:8px;padding:8px 0;border-bottom:1px solid var(--border);font-size:13.5px;color:var(--fg2)}
.checkline:last-child{border-bottom:none}
.checkline span:first-child{width:18px;height:18px;border-radius:5px;background:var(--success-soft);color:var(--success);display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:900;flex-shrink:0;margin-top:2px}
.day-complete{margin-top:16px;width:100%;justify-content:center}
.mentor-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin:0 0 20px;animation:fadeUp .35s}
.mentor-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-sm)}
.mentor-card strong{display:block;font-size:13px;font-weight:850;color:var(--fg);margin-bottom:5px}
.mentor-card p{font-size:12.8px;line-height:1.65;color:var(--fg2)}
.answer-framework{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin:12px 0 4px}
.framework-step{background:var(--accent-soft);border:1px solid var(--accent-glow);border-radius:var(--radius-sm);padding:10px 12px;font-size:12.5px;font-weight:800;color:var(--accent);line-height:1.45}
.score-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin-top:10px}
.score-card{padding:12px 14px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg2)}
.score-card strong{display:block;font-size:13px;color:var(--fg);margin-bottom:4px}
.score-card p{font-size:12.8px;color:var(--fg2);line-height:1.6}
.markdown-doc{max-width:940px;margin:0 auto;animation:fadeUp .35s}
.markdown-doc h1{font-size:30px;line-height:1.25;font-weight:900;color:var(--fg);margin:4px 0 12px}
.markdown-doc h2{font-size:21px;line-height:1.35;font-weight:850;color:var(--fg);margin:32px 0 12px;padding-top:18px;border-top:1px solid var(--border)}
.markdown-doc h3{font-size:15px;font-weight:850;color:var(--fg);margin:18px 0 8px}
.markdown-doc p{font-size:15px;color:var(--fg2);line-height:1.9;margin:10px 0}
.markdown-doc ul,.markdown-doc ol{margin:10px 0 10px 22px;color:var(--fg2);font-size:14.5px;line-height:1.85}
.markdown-doc li{margin:5px 0}
.markdown-doc blockquote{margin:18px 0;padding:12px 16px;border-left:4px solid var(--accent);background:var(--accent-soft);border-radius:0 var(--radius-sm) var(--radius-sm) 0;color:var(--fg2)}
.markdown-doc hr{border:0;border-top:1px solid var(--border);margin:26px 0}
.markdown-doc code{font-family:var(--font-mono);font-size:13px;color:var(--accent);background:var(--code-bg);border:1px solid var(--code-border);border-radius:4px;padding:2px 6px}
.md-kicker{font-size:11px;font-weight:900;letter-spacing:.8px;text-transform:uppercase;color:var(--accent);margin-bottom:8px}
.md-section{padding:2px 0 8px;border-radius:var(--radius-sm)}
.md-section.active{background:linear-gradient(90deg,var(--accent-soft),transparent 72%);padding-left:14px;margin-left:-14px}
.md-pill-row{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 22px}
.md-pill{padding:4px 10px;border-radius:20px;background:var(--accent-soft);border:1px solid var(--accent-glow);color:var(--accent);font-size:12px;font-weight:800}
/* ═══════════ PREMIUM GLASS SKIN ═══════════ */
:root{
 --glass:rgba(255,255,255,.72);
 --glass-strong:rgba(255,255,255,.86);
 --glass-soft:rgba(255,255,255,.48);
 --glass-border:rgba(255,255,255,.66);
 --hairline:rgba(24,24,27,.09);
 --shadow-glass:0 18px 46px rgba(15,23,42,.10),0 1px 0 rgba(255,255,255,.72) inset;
 --shadow-float:0 10px 28px rgba(15,23,42,.08);
}
[data-theme="dark"]{
 --glass:rgba(24,24,27,.64);
 --glass-strong:rgba(39,39,42,.78);
 --glass-soft:rgba(39,39,42,.42);
 --glass-border:rgba(255,255,255,.10);
 --hairline:rgba(255,255,255,.08);
 --shadow-glass:0 18px 48px rgba(0,0,0,.34),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-float:0 12px 34px rgba(0,0,0,.28);
}
body{background:linear-gradient(180deg,#f7f8fb 0%,#eef2f7 46%,#fbfcfd 100%) fixed}
[data-theme="dark"] body{background:linear-gradient(180deg,#09090b 0%,#111318 48%,#08090b 100%) fixed}
body::before{opacity:.24;mix-blend-mode:multiply}
[data-theme="dark"] body::before{opacity:.12;mix-blend-mode:screen}
.topnav{background:var(--glass-strong);border-bottom:1px solid var(--glass-border);box-shadow:0 10px 30px rgba(15,23,42,.06);backdrop-filter:blur(24px) saturate(1.35);-webkit-backdrop-filter:blur(24px) saturate(1.35)}
.sidebar{background:var(--glass);border-right:1px solid var(--glass-border);box-shadow:1px 0 0 var(--hairline),12px 0 38px rgba(15,23,42,.04);backdrop-filter:blur(26px) saturate(1.35);-webkit-backdrop-filter:blur(26px) saturate(1.35)}
.mode-tabs,.search-box,.repo-link,.theme-btn,.timer-btn{background:var(--glass-soft);border:1px solid var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.45) inset}
.mode-btn.active{background:linear-gradient(180deg,#24242a,#111113);color:#fff;box-shadow:0 8px 20px rgba(17,17,19,.18),0 1px 0 rgba(255,255,255,.18) inset}
[data-theme="dark"] .mode-btn.active{background:linear-gradient(180deg,rgba(255,255,255,.22),rgba(255,255,255,.10));box-shadow:0 8px 24px rgba(0,0,0,.32),0 1px 0 rgba(255,255,255,.16) inset}
.section-card,.day-panel,.panel,.hero,.breakdown-hero,.intro-card,.quiz-item,.card-face,.scenario-card,.search-result,.mentor-card,.score-card,.lv-block{background:var(--glass);border:1px solid var(--glass-border);box-shadow:var(--shadow-glass);backdrop-filter:blur(22px) saturate(1.28);-webkit-backdrop-filter:blur(22px) saturate(1.28)}
.section-card:hover,.day-panel:hover,.panel:hover,.search-result:hover,.mentor-card:hover{box-shadow:var(--shadow-glass),0 0 0 1px rgba(99,102,241,.10);transform:translateY(-1px)}
.source-item,pre,.framework-step,.md-pill,.breakdown-pill,.pill,.sub-item.active,.side-item.active,.dim-item.active,.ch-header.active{background:rgba(255,255,255,.56);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.55) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .breakdown-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .side-item.active,[data-theme="dark"] .dim-item.active,[data-theme="dark"] .ch-header.active{background:rgba(255,255,255,.07);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.markdown-doc blockquote,.microcopy,.progress-pill{background:var(--glass-soft);border:1px solid var(--glass-border);box-shadow:var(--shadow-float);backdrop-filter:blur(18px) saturate(1.25);-webkit-backdrop-filter:blur(18px) saturate(1.25)}
.markdown-doc h1,.content-header h1{text-shadow:0 1px 0 rgba(255,255,255,.35)}
[data-theme="dark"] .markdown-doc h1,[data-theme="dark"] .content-header h1{text-shadow:0 1px 0 rgba(0,0,0,.35)}
/* ═══════════ TOOLBAR ═══════════ */
.toolbar{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap;align-items:center;animation:fadeUp .3s}
.tool-btn{display:flex;align-items:center;gap:6px;padding:7px 16px;border-radius:var(--radius-sm);font-size:13px;font-weight:500;background:var(--accent);color:#fff;transition:all .2s;box-shadow:0 2px 6px var(--accent-glow)}
.tool-btn:hover{background:var(--accent2);transform:translateY(-1px);box-shadow:0 4px 12px var(--accent-glow)}
.timer-display{font-size:22px;font-family:var(--font-mono);font-weight:600;color:var(--accent);min-width:90px;letter-spacing:2px;padding:4px 12px;background:var(--accent-soft);border-radius:var(--radius-sm)}
.timer-btn{padding:7px 14px;border-radius:var(--radius-sm);font-size:13px;font-weight:500;border:1px solid var(--border);color:var(--fg2);transition:all .2s}
.timer-btn:hover{border-color:var(--accent);color:var(--accent)}
.timer-btn.running{background:var(--danger);color:#fff;border-color:var(--danger)}
/* ═══════════ APPENDIX ═══════════ */
.appendix-table{width:100%;border-collapse:separate;border-spacing:0;font-size:13.5px;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;animation:fadeUp .4s}
.appendix-table th{background:var(--bg2);font-weight:600;padding:10px 16px;text-align:left;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--fg3);border-bottom:1px solid var(--border)}
.appendix-table td{padding:10px 16px;border-bottom:1px solid var(--border);color:var(--fg2);transition:background .15s}
.appendix-table tr:last-child td{border-bottom:none}
.appendix-table tr:hover td{background:var(--accent-soft)}
/* ═══════════ SEARCH ═══════════ */
.search-results{animation:fadeUp .3s}
.search-result{padding:14px 18px;border:1px solid var(--border);border-radius:var(--radius);margin:8px 0;cursor:pointer;transition:all .2s;background:var(--card)}
.search-result:hover{border-color:var(--accent);box-shadow:var(--shadow-sm);transform:translateY(-1px)}
.search-result .sr-mode{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:var(--accent);margin-bottom:4px}
.search-result .sr-title{font-size:14px;font-weight:600;color:var(--fg)}
.search-result .sr-snippet{font-size:13px;color:var(--fg3);margin-top:4px;line-height:1.5}
mark{background:var(--accent-glow);color:var(--accent);padding:1px 3px;border-radius:3px;font-weight:600}
.sidebar-empty{display:flex;align-items:center;justify-content:center;color:var(--fg3);font-size:13px;padding:40px 20px;text-align:center}
.intro-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:28px;box-shadow:var(--shadow-sm);animation:fadeUp .4s}
.intro-card h3{font-size:17px;font-weight:700;margin-bottom:14px;color:var(--fg)}
.intro-card p{font-size:14.5px;line-height:1.8;color:var(--fg2)}
.intro-card .code-link{font-family:var(--font-mono);font-size:12px;color:var(--fg3);margin-top:10px;display:block}
.intro-card .follow-tag{margin-top:10px;padding:8px 12px;background:var(--warn-soft);border-radius:var(--radius-sm);font-size:12.5px;color:var(--fg2);border-left:3px solid var(--warn)}
/* ═══════════ PREMIUM SURFACE FINAL PASS ═══════════ */
.section-card,.day-panel,.panel,.hero,.breakdown-hero,.intro-card,.quiz-item,.card-face,.scenario-card,.search-result,.mentor-card,.score-card,.lv-block,.appendix-table{background:var(--glass);border:1px solid var(--glass-border);box-shadow:var(--shadow-glass);backdrop-filter:blur(22px) saturate(1.28);-webkit-backdrop-filter:blur(22px) saturate(1.28)}
.section-card:hover,.day-panel:hover,.panel:hover,.search-result:hover,.mentor-card:hover{border-color:var(--glass-border);box-shadow:var(--shadow-glass),0 0 0 1px rgba(99,102,241,.10);transform:translateY(-1px)}
.source-item,pre,.framework-step,.md-pill,.breakdown-pill,.pill,.sub-item.active,.side-item.active,.dim-item.active,.ch-header.active,.appendix-table th{background:rgba(255,255,255,.56);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.55) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .breakdown-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .side-item.active,[data-theme="dark"] .dim-item.active,[data-theme="dark"] .ch-header.active,[data-theme="dark"] .appendix-table th{background:rgba(255,255,255,.07);border-color:var(--glass-border);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.appendix-table td{border-color:var(--glass-border)}
/* ═══════════ PREMIUM DEPTH SYSTEM ═══════════ */
:root{
 --layer-page:
 linear-gradient(135deg,rgba(99,102,241,.14) 0%,rgba(99,102,241,0) 34%),
 linear-gradient(225deg,rgba(20,184,166,.12) 0%,rgba(20,184,166,0) 38%),
 linear-gradient(180deg,#fbfcff 0%,#edf2f8 46%,#f8fafc 100%);
 --layer-main:linear-gradient(180deg,rgba(255,255,255,.38),rgba(255,255,255,.08));
 --glass-nav:rgba(255,255,255,.78);
 --glass-sidebar:rgba(255,255,255,.58);
 --glass-card:rgba(255,255,255,.68);
 --glass-card-strong:rgba(255,255,255,.84);
 --glass-chip:rgba(255,255,255,.50);
 --stroke-strong:rgba(255,255,255,.82);
 --shadow-nav:0 18px 55px rgba(15,23,42,.10),0 1px 0 rgba(255,255,255,.82) inset;
 --shadow-side:14px 0 44px rgba(15,23,42,.07),1px 0 0 rgba(255,255,255,.70) inset;
 --shadow-card-rich:0 22px 64px rgba(15,23,42,.12),0 8px 22px rgba(15,23,42,.06),0 1px 0 rgba(255,255,255,.80) inset;
 --shadow-card-hover-rich:0 28px 76px rgba(15,23,42,.16),0 10px 26px rgba(15,23,42,.08),0 1px 0 rgba(255,255,255,.86) inset;
 --shadow-hero-rich:0 30px 90px rgba(15,23,42,.16),0 1px 0 rgba(255,255,255,.88) inset;
}
[data-theme="dark"]{
 --layer-page:
 linear-gradient(135deg,rgba(99,102,241,.18) 0%,rgba(99,102,241,0) 34%),
 linear-gradient(225deg,rgba(20,184,166,.12) 0%,rgba(20,184,166,0) 38%),
 linear-gradient(180deg,#09090b 0%,#101216 48%,#08090b 100%);
 --layer-main:linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.01));
 --glass-nav:rgba(20,20,23,.76);
 --glass-sidebar:rgba(20,20,23,.62);
 --glass-card:rgba(24,24,27,.64);
 --glass-card-strong:rgba(32,32,36,.74);
 --glass-chip:rgba(255,255,255,.07);
 --stroke-strong:rgba(255,255,255,.13);
 --shadow-nav:0 18px 58px rgba(0,0,0,.42),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-side:14px 0 46px rgba(0,0,0,.28),1px 0 0 rgba(255,255,255,.06) inset;
 --shadow-card-rich:0 24px 68px rgba(0,0,0,.38),0 8px 22px rgba(0,0,0,.22),0 1px 0 rgba(255,255,255,.08) inset;
 --shadow-card-hover-rich:0 30px 78px rgba(0,0,0,.48),0 12px 30px rgba(0,0,0,.26),0 1px 0 rgba(255,255,255,.10) inset;
 --shadow-hero-rich:0 34px 92px rgba(0,0,0,.50),0 1px 0 rgba(255,255,255,.10) inset;
}
body{background:var(--layer-page) fixed}
.app{background:linear-gradient(90deg,rgba(255,255,255,.16),rgba(255,255,255,.02) 42%,rgba(255,255,255,.08))}
[data-theme="dark"] .app{background:linear-gradient(90deg,rgba(255,255,255,.025),rgba(255,255,255,.008) 42%,rgba(255,255,255,.018))}
.main{background:var(--layer-main)}
.topnav{background:var(--glass-nav);border-bottom:1px solid var(--stroke-strong);box-shadow:var(--shadow-nav)}
.topnav::after{background:linear-gradient(90deg,transparent,rgba(99,102,241,.42),rgba(20,184,166,.30),transparent);opacity:1}
.sidebar{background:var(--glass-sidebar);border-right:1px solid var(--stroke-strong);box-shadow:var(--shadow-side)}
.mode-tabs{background:rgba(255,255,255,.42);border:1px solid var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.72) inset,0 10px 26px rgba(15,23,42,.06);padding:4px}
[data-theme="dark"] .mode-tabs{background:rgba(255,255,255,.055);box-shadow:0 1px 0 rgba(255,255,255,.08) inset,0 12px 30px rgba(0,0,0,.26)}
.mode-btn{position:relative;font-weight:700}
.mode-btn.active{background:linear-gradient(180deg,#2b2b31,#111114);box-shadow:0 12px 28px rgba(17,17,19,.24),0 1px 0 rgba(255,255,255,.22) inset}
[data-theme="dark"] .mode-btn.active{background:linear-gradient(180deg,rgba(255,255,255,.20),rgba(255,255,255,.08));box-shadow:0 12px 30px rgba(0,0,0,.36),0 1px 0 rgba(255,255,255,.14) inset}
.search-box,.repo-link,.theme-btn,.timer-btn,.timer-display{background:var(--glass-chip);border:1px solid var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.62) inset,0 10px 26px rgba(15,23,42,.05);backdrop-filter:blur(18px) saturate(1.2);-webkit-backdrop-filter:blur(18px) saturate(1.2)}
[data-theme="dark"] .search-box,[data-theme="dark"] .repo-link,[data-theme="dark"] .theme-btn,[data-theme="dark"] .timer-btn,[data-theme="dark"] .timer-display{box-shadow:0 1px 0 rgba(255,255,255,.08) inset,0 12px 30px rgba(0,0,0,.22)}
.side-title{padding:10px 12px 8px;color:var(--fg3);font-size:11px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.side-item{display:flex;align-items:center;gap:8px;position:relative;min-height:36px;padding:8px 10px 8px 14px;border-radius:var(--radius-sm);color:var(--fg2);font-size:13px;cursor:pointer;transition:background .18s,color .18s,box-shadow .18s,transform .18s}
.side-item::before{content:'';position:absolute;left:6px;top:9px;bottom:9px;width:2px;border-radius:2px;background:transparent;transition:background .18s,top .18s,bottom .18s}
.side-item:hover{background:rgba(255,255,255,.36);color:var(--fg);transform:translateX(1px)}
[data-theme="dark"] .side-item:hover{background:rgba(255,255,255,.055)}
.side-item.active{background:rgba(255,255,255,.62);color:var(--accent);font-weight:800;box-shadow:0 10px 24px rgba(99,102,241,.10),0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .side-item.active{background:rgba(255,255,255,.08);box-shadow:0 12px 28px rgba(0,0,0,.24),0 1px 0 rgba(255,255,255,.08) inset}
.side-item.active::before{top:7px;bottom:7px;background:linear-gradient(180deg,var(--accent),var(--accent2))}
.side-main{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.badge{font-size:10px;padding:2px 7px;border-radius:999px;background:rgba(24,24,27,.06);color:var(--fg3);font-weight:800;flex-shrink:0;border:1px solid rgba(24,24,27,.06)}
[data-theme="dark"] .badge{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.08)}
.side-item.active .badge{background:linear-gradient(180deg,var(--accent),var(--accent2));color:#fff;border-color:transparent;box-shadow:0 6px 16px var(--accent-glow)}
.markdown-doc{background:var(--glass-card-strong);border:1px solid var(--stroke-strong);border-radius:var(--radius);box-shadow:var(--shadow-hero-rich);padding:36px 42px;position:relative;overflow:hidden;backdrop-filter:blur(26px) saturate(1.24);-webkit-backdrop-filter:blur(26px) saturate(1.24)}
.markdown-doc::before{content:'';position:absolute;inset:0 0 auto;height:1px;background:linear-gradient(90deg,transparent,rgba(255,255,255,.92),transparent)}
[data-theme="dark"] .markdown-doc::before{background:linear-gradient(90deg,transparent,rgba(255,255,255,.14),transparent)}
.markdown-doc h1{font-size:32px;letter-spacing:0}
.markdown-doc h2{border-top-color:rgba(24,24,27,.09)}
[data-theme="dark"] .markdown-doc h2{border-top-color:rgba(255,255,255,.09)}
.md-section{padding:2px 0 12px;border-radius:var(--radius-sm);transition:background .22s,padding .22s,margin .22s,box-shadow .22s}
.md-section.active{background:linear-gradient(90deg,rgba(99,102,241,.13),rgba(20,184,166,.07),transparent 78%);padding-left:16px;margin-left:-16px;box-shadow:inset 3px 0 0 var(--accent)}
[data-theme="dark"] .md-section.active{background:linear-gradient(90deg,rgba(129,140,248,.16),rgba(20,184,166,.07),transparent 78%)}
.hero,.breakdown-hero{background:var(--glass-card-strong);border-color:var(--stroke-strong);box-shadow:var(--shadow-hero-rich)}
.section-card,.day-panel,.panel,.intro-card,.quiz-item,.card-face,.scenario-card,.search-result,.mentor-card,.score-card,.lv-block,.appendix-table{background:var(--glass-card);border-color:var(--stroke-strong);box-shadow:var(--shadow-card-rich)}
.section-card:hover,.day-panel:hover,.panel:hover,.quiz-item:hover,.scenario-card:hover,.search-result:hover,.mentor-card:hover{border-color:rgba(99,102,241,.28);box-shadow:var(--shadow-card-hover-rich);transform:translateY(-2px)}
.source-item,pre,.framework-step,.md-pill,.breakdown-pill,.pill,.sub-item.active,.dim-item.active,.ch-header.active,.appendix-table th{background:var(--glass-chip);border-color:var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.62) inset}
[data-theme="dark"] .source-item,[data-theme="dark"] pre,[data-theme="dark"] .framework-step,[data-theme="dark"] .md-pill,[data-theme="dark"] .breakdown-pill,[data-theme="dark"] .pill,[data-theme="dark"] .sub-item.active,[data-theme="dark"] .dim-item.active,[data-theme="dark"] .ch-header.active,[data-theme="dark"] .appendix-table th{background:var(--glass-chip);border-color:var(--stroke-strong);box-shadow:0 1px 0 rgba(255,255,255,.08) inset}
.nav-btn,.tool-btn{box-shadow:0 10px 24px rgba(15,23,42,.08),0 1px 0 rgba(255,255,255,.55) inset}
.nav-btn.primary,.tool-btn.primary,.tool-btn{box-shadow:0 14px 30px var(--accent-glow),0 1px 0 rgba(255,255,255,.24) inset}
/* Nav buttons */
.nav-bar{display:flex;justify-content:space-between;align-items:center;margin-top:28px;padding-top:20px;border-top:1px solid var(--border);gap:12px}
.nav-btn{display:flex;align-items:center;gap:6px;padding:8px 18px;border-radius:var(--radius-sm);font-size:13px;font-weight:500;transition:all .2s;border:1px solid var(--border);color:var(--fg2)}
.nav-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.nav-btn.primary{background:var(--accent);color:#fff;border-color:var(--accent);box-shadow:0 2px 8px var(--accent-glow)}
.nav-btn.primary:hover{background:var(--accent2);transform:translateY(-1px)}
.nav-btn .arrow-icon{font-size:11px;transition:transform .2s}
.nav-btn:hover .arrow-icon{transform:translateX(2px)}
.nav-btn,.tool-btn{box-shadow:0 10px 24px rgba(15,23,42,.08),0 1px 0 rgba(255,255,255,.55) inset}
.nav-btn.primary,.tool-btn.primary,.tool-btn{box-shadow:0 14px 30px var(--accent-glow),0 1px 0 rgba(255,255,255,.24) inset}
/* Keep blur on small, stationary chrome only. Large surfaces inside the
 scrolling pane otherwise force expensive backdrop repaints while scrolling. */
.main .markdown-doc,.main .section-card,.main .day-panel,.main .panel,.main .hero,.main .breakdown-hero,.main .intro-card,.main .quiz-item,.main .card-face,.main .scenario-card,.main .search-result,.main .mentor-card,.main .score-card,.main .lv-block,.main .appendix-table,.main blockquote{
 backdrop-filter:none;
 -webkit-backdrop-filter:none;
}
/* ═══════════ RESPONSIVE ═══════════ */
@media(max-width:900px){
 .sidebar{width:220px;min-width:220px}
 .main{padding:20px 24px 40px}
 .card-grid,.scenario-grid{grid-template-columns:1fr}
 .brand-sub{display:none}
 .search-box{width:160px}.search-box:focus{width:200px}
}
@media(max-width:640px){
 html,body{width:100%;max-width:100%;overflow-x:hidden}
 body{font-size:14px}
 body::before{display:none}
 .topnav{display:flex;flex-direction:column;width:100vw;max-width:100vw;height:auto;min-height:var(--topnav-h);padding:10px 12px;gap:8px;align-items:stretch;overflow:hidden}
 .brand{order:1;width:100%;min-width:0;margin-right:0;padding-right:42px}
 .brand&gt;div:last-child{min-width:0}
 .brand-icon{width:30px;height:30px;flex:0 0 30px}
 .brand-icon svg{width:28px;height:28px}
 .brand-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;letter-spacing:0}
 .brand-sub{display:none}
 .progress-pill{order:2;align-self:flex-start;padding:3px 8px;font-size:11px;white-space:nowrap}
 .theme-btn{position:absolute;top:8px;right:10px;width:32px;height:32px}
 .mode-tabs{order:3;display:flex;flex-direction:column;width:calc(100vw - 24px);max-width:calc(100vw - 24px);min-width:0;gap:4px;overflow:hidden}
 .mode-btn{width:100%;min-width:0;padding:8px 10px;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center}
 .repo-link{order:4;width:calc(100vw - 24px);max-width:calc(100vw - 24px);justify-content:center;min-height:34px}
 .search-wrap{order:5;width:calc(100vw - 24px);max-width:calc(100vw - 24px);min-width:0}
 .search-box,.search-box:focus{width:100%;height:36px;font-size:13px}
 .app{display:block;width:100%;max-width:100%;height:auto;min-height:calc(100dvh - 136px);overflow:visible}
 .sidebar{display:none}
 .main{width:100%;max-width:100%;padding:16px 14px max(40px,env(safe-area-inset-bottom));overflow:visible}
 .markdown-doc{padding:20px 16px;border-radius:8px}
 .content-header{margin-bottom:16px}
 .content-header h1{font-size:22px;letter-spacing:0}
 .section-card,.intro-card{width:100%;max-width:100%;padding:16px 14px;border-radius:8px;margin-bottom:14px;overflow:hidden}
 .section-card h2{font-size:16px;align-items:flex-start;margin-bottom:12px}
 .section-card p,.section-card ul,.section-card ol,.lv-body p,.lv-body ul,.lv-body ol{font-size:13.5px}
 .section-card ul,.section-card ol,.lv-body ul,.lv-body ol{margin-left:18px}
 .lv-header{padding:10px 12px;align-items:flex-start;gap:6px;flex-wrap:wrap}
 .lv-header&gt;span:last-child{min-width:0;margin-left:0!important;flex:1 1 160px!important}
 .lv-body{padding:0 12px}
 .lv-body.open{padding:0 12px 12px;max-height:5000px}
 .lv-body pre,pre{max-width:100%;padding:14px 12px;margin:12px -2px;border-radius:8px;font-size:12px;line-height:1.55}
 pre::before{display:none}
 .quiz-q{padding:12px;gap:8px;flex-wrap:wrap}
 .quiz-q .q-text{flex:1 1 calc(100% - 48px)}
 .quiz-status{margin-left:32px}
 .quiz-body.open{max-height:1200px}
 .quiz-hint{margin:0 12px 12px;padding:12px;font-size:13px}
 .quiz-btns{margin:0 12px 12px;flex-direction:column}
 .quiz-btn{width:100%;padding:8px 12px}
 .toolbar{gap:8px;align-items:stretch}
 .toolbar .search-wrap{width:100%}
 .toolbar .search-box,.toolbar .search-box:focus{width:100%!important}
 .tool-btn,.timer-btn{flex:1 1 120px;justify-content:center}
 .timer-display{flex:1 1 100%;min-width:0;text-align:center}
 .card-grid,.scenario-grid{grid-template-columns:minmax(0,1fr);gap:12px}
 .card{height:360px}
 .card-front{padding:16px}
 .card-back{padding:16px}
 .card-title{font-size:14px}
 .card-actions{flex-wrap:wrap}
 .card-action{flex:1 1 110px;padding:7px 8px;text-align:center}
 .scenario-card{padding:16px}
 .scenario-card h3{font-size:15px;align-items:flex-start}
 .scenario-card .sc-desc,.sc-step-content p{font-size:13px}
 .breakdown-hero{padding:18px 16px}
 .breakdown-hero h2{font-size:21px}
 .breakdown-meta{gap:6px}
 .day-layout{grid-template-columns:minmax(0,1fr);gap:12px}
 .day-panel{padding:16px}
 .sc-step{gap:10px}
 .appendix-table{display:block;overflow-x:auto;white-space:nowrap}
 .appendix-table table{min-width:560px}
 .nav-bar{flex-direction:column;align-items:stretch;margin-top:20px;padding-top:16px}
 .nav-btn{width:100%;justify-content:center;min-height:40px}
 .search-result{padding:12px}
}
@media(max-width:420px){
 .brand{padding-right:42px}
 .card{height:380px}
 .quiz-q .q-num{width:22px;height:22px}
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="topnav"&gt;
 &lt;div class="brand"&gt;
 &lt;div class="brand-icon" aria-label="Go Gopher"&gt;
 &lt;svg viewBox="0 0 64 64" role="img" aria-hidden="true"&gt;
 &lt;ellipse cx="18" cy="24" rx="9" ry="11" fill="#6fd4e6"/&gt;
 &lt;ellipse cx="46" cy="24" rx="9" ry="11" fill="#6fd4e6"/&gt;
 &lt;ellipse cx="32" cy="35" rx="24" ry="20" fill="#74d7e8"/&gt;
 &lt;ellipse cx="23" cy="32" rx="4" ry="5" fill="#111827"/&gt;
 &lt;ellipse cx="41" cy="32" rx="4" ry="5" fill="#111827"/&gt;
 &lt;ellipse cx="32" cy="39" rx="6" ry="4" fill="#27252a"/&gt;
 &lt;rect x="27" y="45" width="10" height="7" rx="2" fill="#fff"/&gt;
 &lt;path d="M32 43v10" stroke="#27252a" stroke-width="2" stroke-linecap="round"/&gt;
 &lt;path d="M13 39c-4 1-7 3-9 6M51 39c4 1 7 3 9 6" stroke="#27252a" stroke-width="3" stroke-linecap="round"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div&gt;&lt;span class="brand-text"&gt;视频Feed流系统&lt;/span&gt;&lt;span class="brand-sub"&gt;（medium）学习&lt;/span&gt;&lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="mode-tabs"&gt;
 &lt;button class="mode-btn active" data-mode="intro" onclick="switchMode('intro')"&gt;前言&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="learn" onclick="switchMode('learn')"&gt;知识学习&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="breakdown" onclick="switchMode('breakdown')"&gt;项目拆解&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="interview" onclick="switchMode('interview')"&gt;面试模拟&lt;/button&gt;
 &lt;button class="mode-btn" data-mode="scenario" onclick="switchMode('scenario')"&gt;场景还原&lt;/button&gt;
 &lt;/div&gt;
 &lt;a class="repo-link" href="https://github.com/LeoninCS/feedsystem_video_go" target="_blank" rel="noopener"&gt;GitHub 仓库&lt;/a&gt;
 &lt;a class="repo-link" href="https://go.botsarena.tech/docs/project-study/study-feed-hard/"&gt;hard 版&lt;/a&gt;
 &lt;div class="search-wrap"&gt;
 &lt;span class="search-icon"&gt;⌕&lt;/span&gt;
 &lt;input type="text" class="search-box" id="searchInput" placeholder="搜索内容..." oninput="handleSearch(this.value)"&gt;
 &lt;/div&gt;
 &lt;button class="theme-btn" onclick="toggleTheme()" title="切换主题"&gt;&lt;span id="themeIcon"&gt;☽&lt;/span&gt;&lt;/button&gt;
 &lt;div class="progress-pill"&gt;&lt;span class="dot"&gt;&lt;/span&gt;&lt;span id="progressText"&gt;0/0&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="app" id="app"&gt;&lt;/div&gt;
&lt;script&gt;
/* ═══════════════════════════════════════════════════
 DATA — 学习文档 6 章 (问答驱动 Lv1/Lv2/Lv3)
 ═══════════════════════════════════════════════════ */
const introData={
title:"视频Feed流系统（medium）7天项目学习",
desc:"medium 版面向第一次系统学习 Feed 项目的人，目标是先把项目跑通、把核心链路讲清楚、把常见面试问题答稳。它适合作为 hard 版之前的主线训练。",
repo:"https://github.com/LeoninCS/feedsystem_video_go",
pillars:[
 {title:"项目介绍",text:"这是一个 Go 短视频 Feed 后端项目，围绕视频发布、Feed 浏览、点赞评论、关注关系、热度排行和异步 Worker 构建学习路径。"},
 {title:"前置要求",text:"建议先具备 Go、Gin、GORM、MySQL、Redis、RabbitMQ、JWT、Docker Compose 和基础系统设计知识。"},
 {title:"Level 1：能跑能演示",text:"能启动服务，体验发布视频、刷 Feed、点赞评论、关注、热度排行等功能。"},
 {title:"Level 2：面试级理解",text:"能讲清 API + Worker 双进程、三层架构、Redis 缓存、RabbitMQ 异步、Outbox、游标分页和推拉结合。"},
 {title:"Level 3：抗追问能力",text:"能回答缓存击穿、MQ 故障、消息重复、幂等消费、冷热分离、JWT 吊销和降级策略。"},
 {title:"Level 4：可独立复刻",text:"能关掉文档，从零复刻 medium 版核心模块：账号鉴权、视频发布、Feed 分页、点赞评论、关注关系、热榜和 Worker 消费。"},
 {title:"Level 5：Feed 流之神",text:"能把 medium 版抽象成 Feed 系统通用方法论，主动讲出分发模型、缓存层级、异步一致性、容量边界和演进方向。"},
 {title:"学习方法",text:"先看前言建立地图，再用知识学习补理论，用项目拆解追 7 天源码，最后用面试模拟和场景还原训练表达。"},
 {title:"最终产出",text:"完成后要有 2 分钟项目介绍、3 条核心链路图、5 条简历亮点和 20 道高频追问答案。"}
],
prerequisites:["Go 基础与错误处理","Gin / GORM / RESTful API","MySQL 事务、索引、唯一约束","Redis 缓存、ZSET、Lua、分布式锁","RabbitMQ 生产消费、Ack、重试","JWT 鉴权与可选认证","Docker Compose 本地启动","缓存、MQ、Feed 流基础设计"],
levelStandards:[
 {standard:"能从本地启动到核心功能演示完整跑一遍。",proof:"能画出发布、刷 Feed、互动三个业务闭环。",next:"进入架构、缓存和 MQ 主线学习。"},
 {standard:"能把项目讲成 API + Worker + MySQL + Redis + RabbitMQ 的工程系统。",proof:"能回答三层架构、Outbox、游标分页、推拉结合和热榜设计。",next:"准备故障、并发、降级和一致性追问。"},
 {standard:"能解释特殊场景下系统怎样保持可用和数据正确。",proof:"能把回答落到源码入口、数据结构和降级方案。",next:"把 medium 版核心链路背到可以复刻。"},
 {standard:"能从零写出 medium 版最小可运行项目。",proof:"能还原目录结构、接口设计、核心表、缓存 key、MQ topic 和关键 Service 编排。",next:"把项目抽象成 Feed 系统设计框架。"},
 {standard:"能从项目上升到通用 Feed 系统方法论。",proof:"能主动讨论时间线、热榜、推拉结合、缓存治理、异步一致性、容量估算和演进路线。",next:"进入 hard 版，学习推荐曝光、Embedding 和更完整工程闭环。"}
],
outputs:["一张项目架构图","三条核心链路图：发布、点赞、刷 Feed","5 条简历亮点","20 道高频面试追问答案","一份 medium 版最小复刻路线图","一套 Feed 系统通用回答框架"],
studyPath:["前言：确认目标和学习深度","知识学习：补齐 Redis、MQ、Feed、Go 工程基础","项目拆解：按 7 天追源码链路","面试模拟：用卡片训练回答结构","场景还原：用端到端和故障题训练追问"]
};
const learnData=[
{id:1,title:"第1章：项目架构总览",topics:[
{q:"为什么采用 API + Worker 双进程架构？",
lv1:`&lt;p&gt;传统单进程架构中，HTTP 请求处理和后台任务（如消息消费、定时轮询）耦合在同一个进程里。这带来几个问题：&lt;/p&gt;</description></item></channel></rss>