AI 提示词:前端网站全栈生成器

3 浏览
1 试用
0 购买
Oct 10, 2025更新

本提示词模板专为网站前端开发设计,能够根据用户需求生成完整的HTML、CSS和JavaScript代码。通过智能分析网站类型、设计风格和功能需求,自动构建响应式布局和交互功能,确保代码的规范性和可维护性。该模板特别适合快速原型开发、教学演示和中小企业官网搭建,支持多种主流设计风格和交互效果,输出代码可直接部署使用或作为进一步开发的基础框架。模板采用模块化设计思路,确保生成代码的结构清晰、语义准确,同时预留充分的定制空间。

示例1

## 网站概述
这是一个为MVP展示页定制的、单文件即可运行的前端网站模板,采用简约现代设计风格,支持以下特性:
- 产品愿景与核心卖点文案(支持A/B测试文案变体)
- 功能列表与路线图(现在 / 下一步 / 未来)
- 报名与反馈表单(姓名/邮箱/用途),本地校验与成功反馈
- FAQ常见问题
- 迭代公告(顶部公告条 + 更新日志)
- 模块拖拽与顺序自定义(桌面端拖拽、移动端按钮上/下移),顺序本地持久化
- 亮/暗/跟随系统 主题切换,主题偏好本地持久化
- 基础SEO(语义化结构、Meta、Open Graph、Twitter卡片、结构化数据)与分析脚本预留位
- 无外部依赖,拷贝即用,符合现代Web标准

注意:A/B测试与分析仅提供前端支持示例(本地存储 + console日志),用于演示与验证,不包含任何外部请求或第三方脚本引用。

## HTML代码
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8" />
  <meta
    name="viewport"
    content="width=device-width, initial-scale=1, viewport-fit=cover"
  />
  <title>NovaFlow - 让产品从0到1更快验证 | MVP展示页</title>
  <meta name="description" content="NovaFlow 帮助团队在一周内完成从原型到可用MVP的迭代闭环。更快验证、更轻交付、更好增长。" />
  <meta name="theme-color" content="#0ea5e9" />
  <link rel="canonical" href="https://example.com/" />

  <!-- Open Graph -->
  <meta property="og:type" content="website">
  <meta property="og:title" content="NovaFlow - 让产品从0到1更快验证">
  <meta property="og:description" content="更快验证、更轻交付、更好增长。A/B测试、拖拽布局、报名表单、迭代公告、亮暗主题。">
  <meta property="og:url" content="https://example.com/">
  <!-- Twitter -->
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="NovaFlow - MVP展示页">
  <meta name="twitter:description" content="一页搞定产品验证与增长必备组件。">

  <!-- 结构化数据:SoftwareApplication + Organization -->
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@graph": [
      {
        "@type": "Organization",
        "name": "NovaFlow",
        "url": "https://example.com",
        "logo": "https://example.com/logo.png"
      },
      {
        "@type": "SoftwareApplication",
        "name": "NovaFlow",
        "applicationCategory": "BusinessApplication",
        "operatingSystem": "Web",
        "description": "帮助团队在一周内完成从原型到MVP的验证闭环:A/B测试、拖拽布局、报名表单、迭代公告、亮暗主题。",
        "offers": { "@type": "Offer", "price": "0", "priceCurrency": "CNY" }
      }
    ]
  }
  </script>

  <!-- Analytics Slot(示例占位,不含外部引用):如需接入第三方分析,将脚本粘贴在此注释下方 -->
  <!--
    示例(请替换为你的供应商脚本,确保合法合规):
    <script>
      // your analytics code
    </script>
  -->

  <style>
    :root {
      --bg: #ffffff;
      --bg-soft: #f7fafc;
      --text: #0f172a;
      --muted: #475569;
      --border: #e2e8f0;
      --primary: #0ea5e9;
      --primary-contrast: #ffffff;
      --accent: #22c55e;
      --warning: #f59e0b;
      --card: #ffffff;
      --shadow: 0 2px 10px rgba(0,0,0,.06);
      --radius: 14px;
      --focus: 0 0 0 3px rgba(14,165,233,.35);
    }
    [data-theme="dark"] {
      --bg: #0b0f14;
      --bg-soft: #0f1720;
      --text: #e5e7eb;
      --muted: #9ca3af;
      --border: #1f2937;
      --primary: #38bdf8;
      --primary-contrast: #0b0f14;
      --accent: #34d399;
      --warning: #fbbf24;
      --card: #0f1720;
      --shadow: 0 4px 16px rgba(0,0,0,.35);
      --focus: 0 0 0 3px rgba(56,189,248,.35);
    }

    * { box-sizing: border-box; }
    html, body { height: 100%; }
    body {
      margin: 0;
      font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
      color: var(--text);
      background: radial-gradient(80rem 60rem at 20% -10%, rgba(14,165,233,.08), transparent 40%),
                  radial-gradient(60rem 40rem at 120% 10%, rgba(34,197,94,.07), transparent 40%),
                  var(--bg);
      line-height: 1.6;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    a { color: var(--primary); text-decoration: none; }
    a:hover { text-decoration: underline; }
    img { max-width: 100%; height: auto; }

    .container {
      width: 100%;
      max-width: 1100px;
      margin: 0 auto;
      padding: 0 20px;
    }

    header.site-header {
      position: sticky;
      top: 0;
      z-index: 50;
      backdrop-filter: saturate(180%) blur(12px);
      background: color-mix(in srgb, var(--bg) 85%, transparent);
      border-bottom: 1px solid var(--border);
    }
    .nav {
      display: flex; align-items: center; justify-content: space-between;
      height: 64px;
    }
    .brand {
      display: flex; align-items: center; gap: 10px; font-weight: 700;
    }
    .brand .logo {
      width: 28px; height: 28px; border-radius: 8px;
      background: linear-gradient(135deg, var(--primary), var(--accent));
      box-shadow: var(--shadow);
    }
    nav ul { list-style: none; display: flex; gap: 18px; margin: 0; padding: 0; }
    nav a { color: var(--muted); font-weight: 600; }
    nav a:hover { color: var(--text); }

    .actions { display: flex; gap: 10px; align-items: center; }
    .btn {
      display: inline-flex; align-items: center; justify-content: center;
      gap: 8px;
      height: 40px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--border);
      background: var(--card); color: var(--text); box-shadow: var(--shadow);
      cursor: pointer; font-weight: 600;
    }
    .btn:hover { transform: translateY(-1px); }
    .btn:focus-visible { outline: none; box-shadow: var(--focus); }
    .btn-primary { background: var(--primary); color: var(--primary-contrast); border-color: transparent; }
    .btn-ghost { background: transparent; border-color: var(--border); }
    .btn-icon { width: 40px; padding: 0; }
    .badge {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 4px 10px; border-radius: 999px; font-size: 12px;
      border: 1px solid var(--border); background: var(--bg-soft); color: var(--muted);
    }

    /* Announcement bar */
    .announcement {
      background: linear-gradient(90deg, color-mix(in srgb, var(--primary) 25%, transparent), transparent);
      border-bottom: 1px dashed var(--border);
      color: var(--muted);
      font-size: 14px;
    }
    .announcement .wrap {
      display: flex; align-items: center; gap: 10px; justify-content: space-between;
      padding: 8px 0;
    }
    .announcement .left { display: flex; align-items: center; gap: 8px; }
    .announcement .close { all: unset; cursor: pointer; color: var(--muted); padding: 4px 8px; border-radius: 6px; }
    .announcement .close:hover { background: var(--bg-soft); }

    /* Modules */
    main { padding: 32px 0 80px; }
    section.module {
      position: relative;
      margin: 22px 0;
      padding: 28px;
      background: var(--card);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
    }
    section.module h2 {
      margin: 0 0 14px;
      font-size: 24px;
      letter-spacing: .2px;
    }
    section.module .sub {
      margin: 0 0 18px; color: var(--muted);
    }

    /* Drag handle + controls */
    .module .drag-handle {
      position: absolute; inset-inline-end: 10px; inset-block-start: 10px;
      display: none; align-items: center; gap: 6px;
      font-size: 12px; color: var(--muted);
      padding: 6px 10px; border-radius: 8px; border: 1px dashed var(--border);
      background: var(--bg-soft); user-select: none;
      cursor: grab;
    }
    .customizing .module .drag-handle { display: inline-flex; }
    .module-controls {
      display: none; gap: 6px; position: absolute; inset-inline-end: 10px; inset-block-start: 48px;
    }
    .customizing .module-controls { display: inline-flex; }
    .module-controls .ctrl {
      height: 28px; width: 28px; border-radius: 8px; border: 1px solid var(--border);
      background: var(--card); color: var(--muted); cursor: pointer;
    }
    .drag-placeholder {
      border: 2px dashed var(--primary);
      background: color-mix(in srgb, var(--primary) 8%, transparent);
      min-height: 60px; border-radius: var(--radius);
      margin: 22px 0;
    }
    .customizing .module { outline: 2px dashed transparent; transition: outline-color .2s; }
    .customizing .module:focus-within { outline-color: color-mix(in srgb, var(--primary) 40%, transparent); }

    /* Hero */
    #hero { padding: 36px; display: grid; gap: 18px; }
    #hero h1 { font-size: 34px; margin: 0; line-height: 1.2; letter-spacing: .2px; }
    .hero-points { display: grid; gap: 10px; }
    .hero-points li { list-style: none; display: flex; gap: 10px; align-items: baseline; color: var(--muted); }
    .ctas { display: flex; gap: 10px; flex-wrap: wrap; padding-top: 6px; }

    /* Features */
    .features-grid {
      display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px;
    }
    .feature-card {
      grid-column: span 6;
      border: 1px solid var(--border); border-radius: 14px; padding: 16px;
      background: var(--bg);
    }
    .feature-card h3 { margin: 6px 0 6px; font-size: 18px; }
    .feature-card p { margin: 0; color: var(--muted); }

    /* Roadmap */
    .roadmap {
      display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
    }
    .road-col { border: 1px solid var(--border); border-radius: 12px; padding: 14px; background: var(--bg); }
    .road-col h3 { margin: 0 0 8px; font-size: 16px; }
    .road-col ul { margin: 0; padding-left: 18px; }
    .tag { display: inline-block; font-size: 12px; padding: 2px 8px; border-radius: 999px; background: var(--bg-soft); border: 1px solid var(--border); color: var(--muted); }

    /* Form */
    form .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
    form .row { display: grid; gap: 6px; }
    label { font-weight: 600; }
    input, select, textarea {
      width: 100%; height: 40px; padding: 8px 10px; border-radius: 10px; border: 1px solid var(--border);
      background: var(--bg); color: var(--text);
    }
    textarea { height: 100px; resize: vertical; }
    .hint { font-size: 12px; color: var(--muted); }
    .form-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
    .success {
      display: none; margin-top: 12px; padding: 10px 12px; border-radius: 12px;
      background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
      color: color-mix(in srgb, var(--accent) 80%, #0b0f14);
    }
    .success.show { display: block; }

    /* FAQ */
    details { border: 1px solid var(--border); border-radius: 12px; padding: 10px 14px; background: var(--bg); }
    details + details { margin-top: 10px; }
    summary { cursor: pointer; font-weight: 600; }
    details[open] { box-shadow: var(--shadow); }

    /* Changelog */
    .changelog-list { display: grid; gap: 10px; }
    .change-item { border: 1px dashed var(--border); border-radius: 12px; padding: 12px; background: var(--bg); }
    .change-item h3 { margin: 0 0 6px; font-size: 16px; }
    .meta { color: var(--muted); font-size: 12px; }

    footer {
      border-top: 1px solid var(--border);
      padding: 24px 0; color: var(--muted); font-size: 14px;
    }
    footer .row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }

    /* Responsive */
    @media (max-width: 900px) {
      .features-grid .feature-card { grid-column: span 12; }
      form .grid { grid-template-columns: 1fr; }
      .roadmap { grid-template-columns: 1fr; }
    }
  </style>
</head>
<body data-theme="auto">
  <!-- 顶部迭代公告条(可关闭,持久化) -->
  <div class="announcement" id="announcement" role="region" aria-label="迭代公告">
    <div class="container">
      <div class="wrap">
        <div class="left">
          <span class="badge">v0.4.2</span>
          <span>新增:拖拽布局、主题偏好持久化、A/B测试变体</span>
        </div>
        <button class="close" id="close-announcement" aria-label="关闭公告">关闭</button>
      </div>
    </div>
  </div>

  <header class="site-header" role="banner">
    <div class="container nav">
      <div class="brand">
        <span class="logo" aria-hidden="true"></span>
        <span>NovaFlow</span>
        <span class="badge" id="ab-badge" title="A/B测试变体">AB: A</span>
      </div>
      <nav aria-label="主导航">
        <ul>
          <li><a href="#hero">概述</a></li>
          <li><a href="#features">功能</a></li>
          <li><a href="#roadmap">路线图</a></li>
          <li><a href="#signup">报名</a></li>
          <li><a href="#faq">FAQ</a></li>
          <li><a href="#changelog">公告</a></li>
        </ul>
      </nav>
      <div class="actions">
        <button class="btn btn-ghost" id="layout-toggle" aria-pressed="false">自定义布局</button>
        <button class="btn btn-ghost" id="layout-reset" title="重置模块顺序">重置</button>
        <button class="btn btn-icon" id="theme-toggle" title="切换主题" aria-label="切换主题">🌓</button>
      </div>
    </div>
  </header>

  <main class="container" id="main">
    <!-- Hero 模块 -->
    <section class="module" id="hero" data-module="hero" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <span class="badge">产品愿景</span>
      <h1 id="hero-title">让产品从0到1更快验证</h1>
      <p class="sub" id="hero-sub">
        NovaFlow 将「洞察-构建-验证-迭代」压缩到一周内:所见即所得模块、A/B测试、表单收集、主题切换与公告管理,帮你用最小成本跑出最大结果。
      </p>
      <ul class="hero-points" aria-label="核心卖点">
        <li>✅ 一页整合验证必需组件,减少上下游沟通成本</li>
        <li>✅ A/B 测试内置,快速定位有效文案与CTA</li>
        <li>✅ 拖拽布局 + 深色模式,提升审美与可用性</li>
        <li>✅ 零依赖纯前端,复制即用,易于接入任意后端</li>
      </ul>
      <div class="ctas">
        <a class="btn btn-primary" href="#signup" id="hero-cta">立即报名体验</a>
        <a class="btn" href="#features">查看功能</a>
      </div>
    </section>

    <!-- 功能列表 -->
    <section class="module" id="features" data-module="features" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <h2>功能一览</h2>
      <p class="sub">覆盖验证闭环的关键模块,低成本高效率。</p>
      <div class="features-grid">
        <article class="feature-card">
          <span class="tag">交互</span>
          <h3>A/B测试引擎</h3>
          <p>URL参数/本地持久化两种分流方式,曝光与CTA点击事件就绪,可接入任意分析。</p>
        </article>
        <article class="feature-card">
          <span class="tag">体验</span>
          <h3>模块拖拽</h3>
          <p>桌面端拖拽排序,移动端按钮上/下移;顺序本地持久化,实验排版更轻松。</p>
        </article>
        <article class="feature-card">
          <span class="tag">品牌</span>
          <h3>亮/暗主题</h3>
          <p>三态:亮 / 暗 / 跟随系统;自动记忆偏好,夜间浏览舒适护眼。</p>
        </article>
        <article class="feature-card">
          <span class="tag">增长</span>
          <h3>报名与反馈</h3>
          <p>姓名/邮箱/用途三要素收集,本地校验与成功反馈,轻松对接你的后端。</p>
        </article>
        <article class="feature-card">
          <span class="tag">发布</span>
          <h3>迭代公告</h3>
          <p>顶部公告条 + 更新日志,让用户一路感知产品进步,增强信任。</p>
        </article>
        <article class="feature-card">
          <span class="tag">SEO</span>
          <h3>基础优化</h3>
          <p>语义结构、元信息与结构化数据,社交卡片预设,助力被正确发现。</p>
        </article>
      </div>
    </section>

    <!-- 路线图 -->
    <section class="module" id="roadmap" data-module="roadmap" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <h2>产品路线图</h2>
      <p class="sub">Now / Next / Later,让方向清晰、节奏明确。</p>
      <div class="roadmap" role="list">
        <div class="road-col" role="listitem" aria-label="现在">
          <h3>现在 <span class="tag">进行中</span></h3>
          <ul>
            <li>报名表单与校验完善</li>
            <li>拖拽布局 + 移动端上/下移</li>
            <li>A/B测试与曝光统计</li>
          </ul>
        </div>
        <div class="road-col" role="listitem" aria-label="下一步">
          <h3>下一步</h3>
          <ul>
            <li>可视化配置面板</li>
            <li>内置数据可视化卡片</li>
            <li>多语言与可访问性增强</li>
          </ul>
        </div>
        <div class="road-col" role="listitem" aria-label="未来">
          <h3>未来</h3>
          <ul>
            <li>服务端事件回传SDK</li>
            <li>模板市场与生态扩展</li>
            <li>插件化能力与团队协作</li>
          </ul>
        </div>
      </div>
    </section>

    <!-- 报名与反馈表单 -->
    <section class="module" id="signup" data-module="signup" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <h2>报名体验 / 反馈建议</h2>
      <p class="sub">留下联系信息,我们会在首批可用时通知你,并邀请加入用户群。</p>

      <form id="lead-form" novalidate>
        <div class="grid">
          <div class="row">
            <label for="name">姓名</label>
            <input id="name" name="name" type="text" placeholder="请输入姓名" required />
          </div>
          <div class="row">
            <label for="email">邮箱</label>
            <input id="email" name="email" type="email" placeholder="name@example.com" required />
          </div>
        </div>
        <div class="row" style="margin-top:12px;">
          <label for="usage">用途 / 使用场景</label>
          <select id="usage" name="usage" required>
            <option value="" selected disabled>请选择你的主要用途</option>
            <option value="企业官网MVP">企业官网MVP</option>
            <option value="产品展示页">产品展示页</option>
            <option value="个人作品集">个人作品集</option>
            <option value="教育培训演示">教育培训演示</option>
            <option value="营销活动页">营销活动页</option>
            <option value="其他">其他</option>
          </select>
          <span class="hint">我们将用于优化模板与优先支持。</span>
        </div>
        <div class="row" style="margin-top:12px;">
          <label for="msg">补充需求(可选)</label>
          <textarea id="msg" name="msg" placeholder="如需特定组件或API对接,请在此说明"></textarea>
        </div>
        <div class="form-actions" style="margin-top:14px;">
          <button type="submit" class="btn btn-primary">提交报名</button>
          <label class="hint"><input type="checkbox" id="agree" checked /> 我同意接收产品更新邮件</label>
        </div>
        <div class="success" id="form-success" role="status" aria-live="polite">
          感谢提交!已记录你的信息(AB变体:<span id="submitted-variant">A</span>)。我们会尽快与你联系。
        </div>
      </form>
    </section>

    <!-- FAQ -->
    <section class="module" id="faq" data-module="faq" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <h2>常见问题 FAQ</h2>
      <details>
        <summary>可以直接上线使用吗?</summary>
        <div>可以。这是零依赖纯前端模板,支持移动端与桌面端。你可以直接部署到静态空间,后续再接后端即可。</div>
      </details>
      <details>
        <summary>A/B 测试如何查看数据?</summary>
        <div>模板内置曝光与CTA点击的console日志与本地存储。接入第三方分析时,将事件上报函数替换为你的SDK。</div>
      </details>
      <details>
        <summary>拖拽排序是否会丢失?</summary>
        <div>模块顺序会保存在浏览器本地(localStorage)。你也可以点击“重置”恢复默认顺序。</div>
      </details>
      <details>
        <summary>表单数据保存在哪里?</summary>
        <div>默认保存在本地存储以便演示。正式环境请改为提交到你的后端或Serverless函数。</div>
      </details>
    </section>

    <!-- 迭代公告 / 更新日志 -->
    <section class="module" id="changelog" data-module="changelog" tabindex="-1">
      <div class="drag-handle" aria-hidden="true">⋮⋮ 拖拽模块</div>
      <div class="module-controls" aria-hidden="true">
        <button class="ctrl" data-move="up" title="上移">↑</button>
        <button class="ctrl" data-move="down" title="下移">↓</button>
      </div>

      <h2>迭代公告</h2>
      <p class="sub">持续小步快跑,快速汇报进展与方向。</p>
      <div class="changelog-list" aria-label="更新列表">
        <article class="change-item">
          <h3>v0.4.2</h3>
          <div class="meta">2025-10-08</div>
          <ul>
            <li>新增:模块拖拽 + 布局持久化</li>
            <li>新增:亮/暗/系统主题切换</li>
            <li>新增:A/B测试变体与曝光、点击埋点接口</li>
          </ul>
        </article>
        <article class="change-item">
          <h3>v0.4.1</h3>
          <div class="meta">2025-09-23</div>
          <ul>
            <li>优化:表单校验与国际化预留</li>
            <li>优化:移动端排版与触控区域</li>
          </ul>
        </article>
      </div>
    </section>
  </main>

  <footer role="contentinfo">
    <div class="container">
      <div class="row">
        <div>© <span id="year"></span> NovaFlow · Made for fast MVP</div>
        <div>
          <span class="badge">主题:<span id="theme-state">auto</span></span>
        </div>
      </div>
    </div>
  </footer>

  <!-- Analytics Slot(页面尾部占位) -->
  <!-- 粘贴你的统计代码到此处(请确保合法合规并遵循隐私政策) -->

  <script>
    (function () {
      const $ = (sel, root=document) => root.querySelector(sel);
      const $$ = (sel, root=document) => Array.from(root.querySelectorAll(sel));

      // ---------- 基础工具 ----------
      const storage = {
        get(key, fallback=null) {
          try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : fallback; } catch { return fallback; }
        },
        set(key, value) {
          try { localStorage.setItem(key, JSON.stringify(value)); } catch {}
        },
        del(key) { try { localStorage.removeItem(key); } catch {} }
      };

      // ---------- Analytics Stub(示例) ----------
      window.analytics = {
        record(event, data={}) {
          // 在此替换为你的分析SDK上报逻辑
          console.log("[analytics]", event, data);
        }
      };

      // ---------- 年份 ----------
      $("#year").textContent = new Date().getFullYear();

      // ---------- 主题切换 ----------
      const themeKey = "nf_theme";
      const themeStateEl = $("#theme-state");
      const themeToggle = $("#theme-toggle");

      function applyTheme(mode) {
        const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
        let actual = mode;
        if (mode === "auto") {
          actual = prefersDark ? "dark" : "light";
        }
        document.body.setAttribute("data-theme", actual);
        themeStateEl.textContent = mode;
      }
      const savedTheme = storage.get(themeKey, "auto");
      applyTheme(savedTheme);

      themeToggle.addEventListener("click", () => {
        const current = themeStateEl.textContent;
        const next = current === "auto" ? "light" : current === "light" ? "dark" : "auto";
        storage.set(themeKey, next);
        applyTheme(next);
        analytics.record("theme_change", { mode: next });
      });

      // ---------- 公告条 ----------
      const ann = $("#announcement");
      const closeAnn = $("#close-announcement");
      const annKey = "nf_ann_closed_v042";
      if (storage.get(annKey, false)) ann.style.display = "none";
      closeAnn.addEventListener("click", () => {
        ann.style.display = "none";
        storage.set(annKey, true);
      });

      // ---------- A/B 测试 ----------
      const abKey = "nf_ab_variant";
      const urlParams = new URLSearchParams(location.search);
      const urlAb = urlParams.get("ab");
      const valid = (v) => v === "A" || v === "B";
      let variant = storage.get(abKey, null);
      if (valid(urlAb)) {
        variant = urlAb;
        storage.set(abKey, variant);
      }
      if (!valid(variant)) {
        variant = Math.random() < 0.5 ? "A" : "B";
        storage.set(abKey, variant);
      }

      document.body.classList.add("ab-" + variant.toLowerCase());
      $("#ab-badge").textContent = "AB: " + variant;

      // 应用变体文案
      const heroTitle = $("#hero-title");
      const heroSub = $("#hero-sub");
      const heroCTA = $("#hero-cta");
      if (variant === "A") {
        heroTitle.textContent = "让产品从0到1更快验证";
        heroSub.textContent = "NovaFlow 将「洞察-构建-验证-迭代」压缩到一周内:所见即所得模块、A/B测试、表单收集、主题切换与公告管理,帮你用最小成本跑出最大结果。";
        heroCTA.textContent = "立即报名体验";
      } else {
        heroTitle.textContent = "用一页,跑通增长闭环";
        heroSub.textContent = "把验证所需的关键环节装进一页:从认知到转化再到复访,用更少的时间验证更大的价值。";
        heroCTA.textContent = "现在就开始";
      }

      // 曝光上报(示例)
      analytics.record("ab_exposure", { variant, path: location.pathname });

      // CTA 点击上报(示例)
      heroCTA.addEventListener("click", () => {
        analytics.record("cta_click", { variant, cta: heroCTA.textContent });
      });

      // ---------- 表单逻辑 ----------
      const form = $("#lead-form");
      const success = $("#form-success");
      const submittedVariant = $("#submitted-variant");
      form.addEventListener("submit", (e) => {
        e.preventDefault();
        const formData = new FormData(form);
        const name = (formData.get("name") || "").trim();
        const email = (formData.get("email") || "").trim();
        const usage = formData.get("usage") || "";
        const msg = (formData.get("msg") || "").trim();
        const agree = $("#agree").checked;

        // 简单校验
        const emailOK = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
        if (!name || !emailOK || !usage) {
          alert("请完整填写姓名、合法邮箱与用途。");
          return;
        }
        // 本地存储演示
        const leadsKey = "nf_leads";
        const leads = storage.get(leadsKey, []);
        leads.push({ name, email, usage, msg, agree, ts: Date.now(), variant });
        storage.set(leadsKey, leads);

        submittedVariant.textContent = variant;
        success.classList.add("show");
        analytics.record("form_submit", { variant, usage });
        form.reset();
      });

      // ---------- 模块拖拽与排序 ----------
      const main = $("#main");
      const modules = () => $$(".module", main);
      const orderKey = "nf_module_order";

      // 应用排序
      const savedOrder = storage.get(orderKey, null);
      if (Array.isArray(savedOrder) && savedOrder.length) {
        const idSet = new Set(savedOrder);
        modules()
          .sort((a, b) => {
            const ia = savedOrder.indexOf(a.id);
            const ib = savedOrder.indexOf(b.id);
            return (ia === -1 ? 999 : ia) - (ib === -1 ? 999 : ib);
          })
          .forEach(el => main.appendChild(el));
      }

      function persistOrder() {
        const order = modules().map(m => m.id);
        storage.set(orderKey, order);
      }

      // 自定义布局开关
      const layoutToggle = $("#layout-toggle");
      const layoutReset = $("#layout-reset");
      let customizing = false;
      layoutToggle.addEventListener("click", () => {
        customizing = !customizing;
        document.body.classList.toggle("customizing", customizing);
        layoutToggle.setAttribute("aria-pressed", String(customizing));
        modules().forEach(m => m.setAttribute("draggable", customizing ? "true" : "false"));
        analytics.record("layout_customizing", { on: customizing });
      });
      layoutReset.addEventListener("click", () => {
        // 恢复默认顺序(按DOM原始序)
        storage.del(orderKey);
        location.reload();
      });

      // 移动端辅助按钮(上/下移)
      $$(".module-controls .ctrl").forEach(btn => {
        btn.addEventListener("click", (e) => {
          const mod = e.target.closest(".module");
          if (!mod) return;
          if (e.target.dataset.move === "up" && mod.previousElementSibling) {
            main.insertBefore(mod, mod.previousElementSibling);
          } else if (e.target.dataset.move === "down" && mod.nextElementSibling) {
            const next = mod.nextElementSibling.nextElementSibling;
            main.insertBefore(mod, next);
          }
          persistOrder();
        });
      });

      // 桌面端拖拽
      let dragging = null;
      let placeholder = null;

      function createPlaceholder(height) {
        const ph = document.createElement("div");
        ph.className = "drag-placeholder";
        ph.style.height = height + "px";
        return ph;
      }

      main.addEventListener("dragstart", (e) => {
        const mod = e.target.closest(".module");
        if (!customizing || !mod) return;
        dragging = mod;
        placeholder = createPlaceholder(mod.offsetHeight);
        mod.style.opacity = "0.5";
        analytics.record("module_drag_start", { id: mod.id });
      });

      main.addEventListener("dragend", (e) => {
        if (!dragging) return;
        dragging.style.opacity = "";
        if (placeholder && placeholder.parentNode) {
          placeholder.parentNode.replaceChild(dragging, placeholder);
        }
        dragging = null;
        placeholder = null;
        persistOrder();
        analytics.record("module_drag_end", {});
      });

      main.addEventListener("dragover", (e) => {
        if (!customizing || !dragging) return;
        e.preventDefault();
        const after = getDragAfterElement(main, e.clientY);
        if (!placeholder) placeholder = createPlaceholder(dragging.offsetHeight);
        if (after == null) {
          main.appendChild(placeholder);
        } else {
          main.insertBefore(placeholder, after);
        }
      });

      function getDragAfterElement(container, y) {
        const els = modules().filter(el => el !== dragging);
        let closest = { offset: Number.NEGATIVE_INFINITY, element: null };
        els.forEach(child => {
          const box = child.getBoundingClientRect();
          const offset = y - box.top - box.height / 2;
          if (offset < 0 && offset > closest.offset) {
            closest = { offset, element: child };
          }
        });
        return closest.element;
      }

      // ---------- 可访问性增强 ----------
      // 键盘辅助:在自定义模式下,模块获得焦点时,按Alt+↑ / Alt+↓ 进行上/下移
      main.addEventListener("keydown", (e) => {
        if (!customizing || !e.target.classList.contains("module")) return;
        if (e.altKey && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
          e.preventDefault();
          const mod = e.target;
          if (e.key === "ArrowUp" && mod.previousElementSibling) {
            main.insertBefore(mod, mod.previousElementSibling);
          } else if (e.key === "ArrowDown" && mod.nextElementSibling) {
            const next = mod.nextElementSibling.nextElementSibling;
            main.insertBefore(mod, next);
          }
          persistOrder();
          analytics.record("module_reorder_keyboard", { id: mod.id });
        }
      });
    })();
  </script>
</body>
</html>
```

## CSS样式
```css
/* 已内联至HTML的<style>中;若需拆分外链,请将以下内容保存为 styles.css 并移除HTML内联样式。 */

/* 见HTML代码块中的<style>,内容完全一致 */
```

## JavaScript功能
```javascript
// 已内联至HTML的<script>中;若需拆分外链,请将以下内容保存为 app.js 并在HTML底部以 <script src="app.js"></script> 引入。

// 见HTML代码块中的<script>,内容完全一致
```

## 使用说明
- 本地预览
  1. 将上述HTML保存为 index.html(已内联CSS/JS,单文件可运行)。
  2. 双击用浏览器打开,或使用任意静态服务器(如 VS Code Live Server)打开。

- A/B测试
  - 默认随机分配到 A 或 B,存储于 localStorage(键:nf_ab_variant)。
  - 可通过URL强制指定:?ab=A 或 ?ab=B。
  - 曝光与CTA点击以 console 日志打印,替换 window.analytics.record 即可接第三方分析。

- 模块拖拽
  - 点击“自定义布局”开启编辑模式(桌面端可拖拽,移动端用上/下移按钮)。
  - 修改顺序后自动保存到 localStorage(键:nf_module_order)。
  - 点击“重置”恢复默认顺序。

- 主题切换
  - 亮 / 暗 / 跟随系统 三态循环切换,状态展示在页脚,持久化键:nf_theme。

- 表单
  - 本模板不发起外部请求。提交后会在本地存储演示数据(键:nf_leads),并显示成功提示。
  - 请在生产环境中将提交逻辑改为调用你的后端API或Serverless函数。

- 迭代公告
  - 顶部公告可关闭,状态持久化(键:nf_ann_closed_v042)。
  - 更新日志在“迭代公告”模块中维护。

- SEO与分析脚本位
  - 已包含基础Meta、Open Graph、Twitter、结构化数据。
  - 头部与尾部均预留分析脚本位,按需粘贴你方脚本,确保合法合规与隐私政策。

## 定制建议
- UI定制
  - 在:root中调整CSS变量以快速更换品牌色与圆角、阴影风格。
  - 为feature-card添加SVG图标以增强识别度(建议内联SVG,避免外部引用)。

- A/B扩展
  - 将变体范围扩展到CTA颜色、模块顺序或价格呈现方式;使用同一ab_variant标识统一管理。
  - 接入后端或第三方分析时,将analytics.record替换为实际埋点上报。

- 表单与合规
  - 接入后端时请新增CSRF、防重复提交、机器人校验(如验证码/延迟提交)等安全措施。
  - 添加隐私政策与用户协议链接,确保数据合规。

- 性能优化
  - 部署时开启HTTP压缩与缓存;对图片资源使用现代格式(WebP/AVIF),本模板无外部资源可直接上线。
  - 若模块较多,可按需拆分JS并采用defer加载(当前为内联单文件模式)。

- 可访问性
  - 为关键按钮与链接补充更丰富的ARIA属性与键盘操作说明。
  - 检查对比度与焦点可视化以满足WCAG标准。

- 国际化
  - 为文案创建字典文件,按浏览器语言或URL参数切换;为日期与数字格式提供本地化格式化。

如需我根据你的品牌与产品信息进一步定制文案、配色与模块结构,请提供产品名称、目标用户、核心场景与竞品对比等信息。

示例2

## 网站概述
这是一个教学示例页,面向前端入门与进阶教学场景。它具备以下特性与技术实现:
- 一键生成标准化页面结构(导航/主视觉/内容区/页脚),并可复制代码片段。
- 提供可切换的布局方案(CSS Grid 与 Flexbox),配套代码讲解与响应式断点注释。
- 内置示例数据填充卡片列表,便于教学展示。
- 作业提交表单与“待评分”占位展示,支持导出表单数据。
- 支持导出代码(HTML/CSS/JS)与讲义(Markdown),以及页面快照。
- 完整的语义化与无障碍(a11y)实践:跳转主内容、ARIA提示、表单标签关联、清晰焦点样式等。
- 响应式设计,适配移动端与桌面端。

技术栈与规范:
- HTML5 语义化标签和可访问性属性
- CSS3 变量、Flexbox、Grid、媒体查询断点
- 原生 JavaScript,无外部依赖,确保安全与可维护性
- 无外部资源引用(图片用内联SVG),符合中国法律法规与社会主义核心价值观

---

## HTML代码
```html
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <meta name="description" content="前端教学示例页:标准化结构、一键生成、布局切换、响应式断点、作业提交与导出讲义。">
  <title>前端教学示例页 · 标准化结构与响应式布局演示</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <!-- 跳转主内容的无障碍链接 -->
  <a class="skip-link" href="#main">跳转到主内容</a>

  <header class="site-header" role="banner">
    <div class="container header-inner">
      <a class="brand" href="#" aria-label="网站品牌标识">教学示例页</a>
      <button id="menuToggle" class="menu-toggle" aria-expanded="false" aria-controls="siteNav">菜单</button>
      <nav id="siteNav" class="site-nav" aria-label="主导航">
        <ul>
          <li><a href="#hero">简介</a></li>
          <li><a href="#a11y">无障碍与语义化</a></li>
          <li><a href="#layout">布局演示</a></li>
          <li><a href="#codeDoc">代码讲解</a></li>
          <li><a href="#assignment">作业提交</a></li>
          <li><a href="#export">导出工具</a></li>
        </ul>
      </nav>
    </div>
  </header>

  <main id="main" tabindex="-1">
    <!-- 主视觉区 -->
    <section id="hero" class="hero" aria-label="主视觉与快速操作">
      <div class="container hero-inner">
        <div class="hero-text">
          <h1>前端教学示例:结构、布局与交互</h1>
          <p>一键生成标准化页面结构,演示响应式栅格与断点注释,切换Grid / Flex布局方案,提供代码片段讲解与作业提交/导出工具。</p>
          <div class="hero-actions">
            <button id="generateStructureBtn" class="btn primary">一键生成标准化结构</button>
            <button id="exportHandoutBtn" class="btn">导出讲义(Markdown)</button>
          </div>
        </div>
        <div class="hero-art" aria-hidden="true">
          <!-- 内联SVG,避免外部资源 -->
          <svg width="220" height="140" viewBox="0 0 220 140" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="教学示意图">
            <rect x="5" y="5" width="210" height="130" rx="10" fill="#E6F0FF" stroke="#2B6CB0" stroke-width="2"/>
            <rect x="15" y="20" width="190" height="20" rx="4" fill="#CDE2FF"/>
            <rect x="15" y="50" width="90" height="70" rx="6" fill="#D9F2E6"/>
            <rect x="115" y="50" width="90" height="70" rx="6" fill="#FFEFD2"/>
            <text x="110" y="35" text-anchor="middle" font-size="12" fill="#2B6CB0">Nav / Hero / Grid / Footer</text>
          </svg>
        </div>
      </div>
      <div class="container">
        <div id="structurePreview" class="structure-preview" aria-live="polite" aria-atomic="true"></div>
      </div>
    </section>

    <!-- 无障碍与语义化提示 -->
    <section id="a11y" class="section">
      <div class="container">
        <h2>无障碍与语义化提示</h2>
        <ul class="a11y-list">
          <li>使用语义化标签:header、nav、main、section、article、footer。</li>
          <li>为交互控件添加可访问性属性:aria-label、aria-controls、aria-live、aria-expanded。</li>
          <li>提供“跳转主内容”链接,确保键盘导航与焦点可见。</li>
          <li>表单使用label显式关联输入框,错误提示与说明文本可被读屏识别。</li>
          <li>颜色对比充足,状态变化不只依赖颜色;提供可视化焦点样式。</li>
        </ul>
      </div>
    </section>

    <!-- 布局演示 -->
    <section id="layout" class="section">
      <div class="container">
        <div class="section-head">
          <h2>响应式布局演示(栅格与断点)</h2>
          <p>选择不同布局方案并查看代码片段与断点注释。栅格示例在小屏 1 列,中屏 2 列,大屏 3 列。</p>
        </div>

        <div class="controls" role="group" aria-label="布局切换控制">
          <div class="control-group">
            <span class="label">布局方案:</span>
            <label><input type="radio" name="layoutMode" value="grid" checked> Grid 栅格</label>
            <label><input type="radio" name="layoutMode" value="flex"> Flex 弹性</label>
          </div>
          <div class="control-group">
            <label><input type="checkbox" id="showBreakpoints"> 显示断点辅助栏</label>
          </div>
          <div class="control-group">
            <button id="resetDataBtn" class="btn">重置示例数据</button>
          </div>
        </div>

        <div id="breakpointBar" class="breakpoint-bar" aria-hidden="true">
          <div class="container">
            <strong>断点参考:</strong>
            <span>SM ≥ 640px</span>
            <span>MD ≥ 960px</span>
            <span>LG ≥ 1200px(容器最大宽度)</span>
          </div>
        </div>

        <div id="layoutWrapper" class="layout-wrapper layout-grid">
          <div id="cardContainer" class="cards" aria-live="polite" aria-busy="false">
            <!-- JS渲染示例卡片 -->
          </div>
        </div>
      </div>
    </section>

    <!-- 代码讲解 -->
    <section id="codeDoc" class="section">
      <div class="container">
        <div class="section-head">
          <h2>代码片段讲解</h2>
          <p>可复制 HTML / CSS 片段,配套注释,便于课堂讲解与自学复盘。</p>
        </div>
        <div class="code-tabs" role="tablist" aria-label="代码片段标签">
          <button class="tab-btn active" data-target="htmlSnippet" role="tab" aria-selected="true">HTML片段</button>
          <button class="tab-btn" data-target="cssSnippet" role="tab" aria-selected="false">CSS片段</button>
          <button id="copySnippetBtn" class="btn small">复制当前片段</button>
        </div>
        <div class="code-panels">
          <pre id="htmlSnippet" class="code-block" aria-label="HTML代码片段"><code></code></pre>
          <pre id="cssSnippet" class="code-block hidden" aria-label="CSS代码片段"><code></code></pre>
        </div>
      </div>
    </section>

    <!-- 作业提交 -->
    <section id="assignment" class="section">
      <div class="container">
        <h2>作业提交表单与评分占位</h2>
        <form id="assignmentForm" class="form" novalidate aria-labelledby="assignmentTitle">
          <div class="form-grid">
            <div class="form-item">
              <label for="studentName">姓名</label>
              <input id="studentName" name="studentName" type="text" required placeholder="例如:张三" aria-describedby="nameHelp">
              <small id="nameHelp" class="muted">使用真实姓名,便于确认成绩。</small>
            </div>
            <div class="form-item">
              <label for="studentEmail">邮箱</label>
              <input id="studentEmail" name="studentEmail" type="email" required placeholder="example@domain.com">
            </div>
            <div class="form-item">
              <label for="assignmentTitle">作业标题</label>
              <input id="assignmentTitle" name="assignmentTitle" type="text" required placeholder="响应式布局练习">
            </div>
            <div class="form-item">
              <label for="assignmentLink">作品链接</label>
              <input id="assignmentLink" name="assignmentLink" type="url" placeholder="https://example.com/demo" aria-describedby="linkHelp">
              <small id="linkHelp" class="muted">可填写在线预览地址或仓库链接。</small>
            </div>
            <div class="form-item">
              <label for="assignmentFile">上传文件(可选)</label>
              <input id="assignmentFile" name="assignmentFile" type="file" aria-describedby="fileHelp">
              <small id="fileHelp" class="muted">本地预览用,不会上传到服务器。</small>
            </div>
            <div class="form-item form-item--full">
              <label for="assignmentDesc">作业说明</label>
              <textarea id="assignmentDesc" name="assignmentDesc" rows="4" maxlength="500" placeholder="简要说明你的设计思路与实现细节…" aria-describedby="descCount"></textarea>
              <small id="descCount" class="muted" aria-live="polite">0 / 500</small>
            </div>
            <div class="form-item">
              <label><input id="agreePolicy" type="checkbox" required> 我已阅读并同意课堂提交规范</label>
            </div>
          </div>
          <div class="form-actions">
            <button type="submit" class="btn primary">提交作业</button>
            <button type="reset" class="btn">清空表单</button>
            <button type="button" id="exportFormDataBtn" class="btn">导出表单数据(JSON)</button>
          </div>
          <div id="formErrors" class="form-errors" aria-live="assertive"></div>
        </form>

        <div class="submissions">
          <h3>提交列表(评分占位)</h3>
          <ul id="submissionList" class="submission-list">
            <!-- JS添加条目 -->
          </ul>
        </div>
      </div>
    </section>

    <!-- 导出工具 -->
    <section id="export" class="section">
      <div class="container">
        <h2>导出代码与讲义</h2>
        <p class="muted">可导出当前页面快照(内联CSS/JS),或分别导出HTML/CSS/JS源文件与课堂讲义。</p>
        <div class="export-actions">
          <button id="exportHTMLBtn" class="btn">导出 HTML</button>
          <button id="exportCSSBtn" class="btn">导出 CSS</button>
          <button id="exportJSBtn" class="btn">导出 JS</button>
          <button id="exportSnapshotBtn" class="btn">导出页面快照(自包含)</button>
        </div>
      </div>
    </section>
  </main>

  <footer class="site-footer" role="contentinfo">
    <div class="container footer-inner">
      <p>© 2025 教学示例页。用于教学演示,遵循 Web 标准与中国法律法规。</p>
      <nav aria-label="页脚导航">
        <a href="#hero">回到顶部</a>
      </nav>
    </div>
  </footer>

  <!-- 辅助:无障碍播报区域 -->
  <div id="announce" class="sr-only" aria-live="polite" aria-atomic="true"></div>

  <script defer src="script.js"></script>
</body>
</html>
```

---

## CSS样式
```css
/* 基础主题变量与重置 */
:root{
  --bg: #ffffff;
  --text: #1a1a1a;
  --muted: #6b7280;
  --primary: #2B6CB0;   /* 教学友好蓝 */
  --accent: #10B981;    /* 成功绿 */
  --warn: #D97706;      /* 提醒橙 */
  --surface: #f6f7fb;
  --border: #e5e7eb;
  --radius: 10px;
  --shadow: 0 6px 20px rgba(0,0,0,0.08);

  /* 容器与断点 */
  --maxw: 1200px;
  --bp-sm: 640px;   /* SM:小屏断点,≥640px 开始两列 */
  --bp-md: 960px;   /* MD:中屏断点,≥960px 开始三列 */
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", "PingFang SC", "Microsoft YaHei", sans-serif;
  color:var(--text);
  background:var(--bg);
  line-height:1.6;
}
img{max-width:100%;display:block}
a{color:var(--primary);text-decoration:none}
a:hover{text-decoration:underline}

/* 可见焦点(无障碍) */
:focus-visible{
  outline:3px solid #93C5FD;
  outline-offset:2px;
}

/* 容器与通用区块 */
.container{max-width:var(--maxw);margin:0 auto;padding:0 16px}
.section{padding:48px 0}
.section-head h2{margin:0 0 8px}
.section-head p{color:var(--muted);margin:0 0 24px}

/* 跳转主内容 */
.skip-link{
  position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;
}
.skip-link:focus{
  position:fixed;left:16px;top:16px;width:auto;height:auto;padding:8px 12px;
  background:#111;color:#fff;border-radius:6px;z-index:1000;
}

/* 头部导航 */
.site-header{background:#f8fbff;border-bottom:1px solid var(--border)}
.header-inner{display:flex;align-items:center;gap:16px;padding:12px 0}
.brand{font-weight:700;color:var(--primary)}
.menu-toggle{
  margin-left:auto;
  padding:8px 12px;border:1px solid var(--border);background:#fff;border-radius:8px;cursor:pointer;
}
.site-nav ul{
  display:flex;gap:16px;list-style:none;margin:0;padding:0;
}
.site-nav a{padding:8px;border-radius:8px}
.site-nav a:hover{background:#eef6ff}

@media (max-width: 720px){
  .menu-toggle{order:2}
  .site-nav{display:none;order:3}
  .site-nav.open{display:block}
  .site-nav ul{flex-direction:column;padding:8px 0}
}

/* 主视觉 */
.hero{padding:40px 0 16px;background:linear-gradient(180deg,#F0F7FF,#fff)}
.hero-inner{display:grid;grid-template-columns:1fr 260px;gap:24px;align-items:center}
.hero-text h1{margin:0 0 8px}
.hero-text p{margin:0 0 16px;color:var(--muted)}
.hero-actions{display:flex;gap:12px;flex-wrap:wrap}
.hero-art{justify-self:end}
.structure-preview{
  margin-top:16px;padding:16px;border:1px dashed var(--border);border-radius:var(--radius);background:var(--surface);
}

@media (max-width: 780px){
  .hero-inner{grid-template-columns:1fr}
  .hero-art{justify-self:start}
}

/* 按钮 */
.btn{
  appearance:none;border:1px solid var(--border);background:#fff;color:var(--text);
  padding:10px 14px;border-radius:10px;cursor:pointer;box-shadow:var(--shadow);
}
.btn:hover{background:#f2f6ff}
.btn.primary{background:var(--primary);border-color:transparent;color:#fff}
.btn.primary:hover{filter:brightness(1.05)}
.btn.small{padding:6px 10px;font-size:14px}

/* 布局演示控制区 */
.controls{
  display:flex;flex-wrap:wrap;gap:16px;align-items:center;margin:8px 0 16px;
}
.control-group{display:flex;gap:12px;align-items:center}
.label{color:#374151}

/* 断点辅助栏(可开关显示) */
.breakpoint-bar{
  position:sticky;top:0;z-index:500;background:#111;color:#fff;padding:8px 0;margin-bottom:12px;
  display:none;
}
.breakpoint-bar .container{display:flex;gap:20px;align-items:center}
.breakpoint-bar .container span{opacity:0.85}

/* 布局外层:用于切换布局方案类名 */
.layout-wrapper{}

/* 卡片列表通用样式 */
.cards{gap:16px}
.card{
  background:#fff;border:1px solid var(--border);border-radius:12px;padding:16px;box-shadow:var(--shadow);
  display:flex;flex-direction:column;gap:8px;
}
.card-header{display:flex;align-items:center;gap:12px}
.card-title{font-weight:700;margin:0}
.card-desc{color:var(--muted);margin:0}
.card-tags{display:flex;gap:8px;flex-wrap:wrap}
.tag{font-size:12px;color:#0F766E;background:#E6FFFA;border:1px solid #99F6E4;border-radius:999px;padding:2px 8px}
.card-actions{margin-top:auto;display:flex;gap:8px}

/* 布局方案 A:Grid 栅格 */
.layout-grid .cards{
  display:grid;
  grid-template-columns: 1fr;    /* 默认:小屏 1 列 */
}

/* 断点注释:
   @media (min-width: 640px) => SM:两列
   @media (min-width: 960px) => MD:三列
*/
@media (min-width: 640px){
  .layout-grid .cards{ grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 960px){
  .layout-grid .cards{ grid-template-columns: repeat(3, 1fr); }
}

/* 布局方案 B:Flex 弹性 */
.layout-flex .cards{
  display:flex; flex-wrap:wrap;
}
.layout-flex .card{
  width:100%;
}
@media (min-width: 640px){
  .layout-flex .card{ width: calc(50% - 8px); } /* 两列,减去gap一半 */
}
@media (min-width: 960px){
  .layout-flex .card{ width: calc(33.333% - 10.7px); } /* 三列 */
}

/* 代码区 */
.code-tabs{display:flex;gap:8px;align-items:center;margin-bottom:8px}
.tab-btn{padding:8px 12px;border:1px solid var(--border);border-radius:8px;background:#fff;cursor:pointer}
.tab-btn.active{background:#EEF6FF;border-color:#BFDBFE}
.code-block{
  border:1px solid var(--border);border-radius:12px;background:#0B1020;color:#E5EDFF;
  padding:16px;overflow:auto;box-shadow:var(--shadow);max-height:60vh;
}
.code-block.hidden{display:none}
.code-block code{font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace}

/* 表单 */
.form-grid{
  display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:12px;
}
.form-item{display:flex;flex-direction:column;gap:8px}
.form-item--full{grid-column:1 / -1}
label{font-weight:600}
input[type="text"], input[type="email"], input[type="url"], input[type="file"], textarea{
  width:100%;padding:10px;border:1px solid var(--border);border-radius:8px;background:#fff;
}
input:focus, textarea:focus{border-color:#93C5FD;box-shadow:0 0 0 3px #DBEAFE}
.form-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:4px}
.form-errors{margin-top:12px;color:#B91C1C;background:#FEF2F2;border:1px solid #FECACA;padding:10px;border-radius:8px;display:none}
.muted{color:var(--muted)}

/* 提交列表 */
.submission-list{
  list-style:none;margin:12px 0 0;padding:0;display:grid;gap:12px;
}
.submission-item{
  border:1px solid var(--border);border-radius:10px;padding:12px;background:#fff;box-shadow:var(--shadow);
  display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center;
}
.submission-meta{color:var(--muted);font-size:14px}
.grade-placeholder{color:#374151;background:#FFF7ED;border:1px dashed #FED7AA;padding:6px 8px;border-radius:8px}

/* 页脚 */
.site-footer{margin-top:32px;border-top:1px solid var(--border);background:#fafafa}
.footer-inner{display:flex;justify-content:space-between;align-items:center;padding:16px 0}

/* 小屏优化 */
@media (max-width: 780px){
  .form-grid{grid-template-columns:1fr}
  .submission-item{grid-template-columns:1fr}
}
```

---

## JavaScript功能
```javascript
/* 教学示例页交互脚本
   - 一键生成标准化结构
   - 布局方案切换(Grid/Flex)与代码片段更新
   - 示例数据渲染/重置
   - 作业提交表单验证与“待评分”占位
   - 导出代码与讲义/页面快照
   - 无障碍:ARIA 播报、可见焦点、键盘友好菜单
*/

(function(){
  const qs = (s, p=document) => p.querySelector(s);
  const qsa = (s, p=document) => Array.from(p.querySelectorAll(s));
  const announce = (msg) => {
    const el = qs('#announce');
    el.textContent = msg;
    // 清空以便下一次读屏触发
    setTimeout(()=>{ el.textContent = ''; }, 1200);
  };

  // 示例数据(可按需扩展或替换)
  const sampleItems = [
    {title:'导航与信息架构', desc:'演示 header/nav/main/footer 的标准化结构。', tags:['HTML5','语义化']},
    {title:'主视觉模块', desc:'教学友好主视觉区,呼出核心CTA与示意图。', tags:['UX','Hero']},
    {title:'Grid 栅格', desc:'小屏1列,中屏2列,大屏3列的响应式示例。', tags:['CSS Grid','响应式']},
    {title:'Flex 弹性布局', desc:'等宽卡片换行布局,配合断点调整列数。', tags:['Flexbox','布局']},
    {title:'无障碍实践', desc:'跳转主内容、焦点可见、ARIA提示等。', tags:['a11y','可访问性']},
    {title:'代码片段讲解', desc:'HTML/CSS片段切换与复制,配套注释。', tags:['教学','代码']},
    {title:'作业提交表单', desc:'必填项校验、字符计数与数据导出。', tags:['表单','验证']},
    {title:'评分占位', desc:'提交列表内展示“待评分”状态。', tags:['评分','占位']},
    {title:'示例数据填充', desc:'内置卡片数据,用于课堂展示。', tags:['数据','演示']},
    {title:'导出工具', desc:'导出HTML/CSS/JS与讲义Markdown。', tags:['导出','工具']},
    {title:'移动端适配', desc:'在窄屏下菜单折叠、表单单列。', tags:['移动端','适配']},
    {title:'性能与规范', desc:'简洁结构,无外部依赖,安全可靠。', tags:['规范','性能']},
  ];

  // 结构生成的标准化模板
  const STANDARD_STRUCTURE_HTML = `<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>标准化页面结构示例</title>
</head>
<body>
  <a class="skip-link" href="#main">跳转到主内容</a>
  <header role="banner">
    <nav aria-label="主导航">
      <ul>
        <li><a href="#hero">简介</a></li>
        <li><a href="#content">内容区</a></li>
        <li><a href="#footer">页脚</a></li>
      </ul>
    </nav>
  </header>
  <main id="main">
    <section id="hero" aria-label="主视觉">
      <h1>主视觉标题</h1>
      <p>副标题或引导语</p>
      <button>主要操作</button>
    </section>
    <section id="content" aria-label="内容区">
      <article>
        <h2>模块标题</h2>
        <p>模块内容文本示例。</p>
      </article>
    </section>
  </main>
  <footer id="footer" role="contentinfo">
    <small>© 示例页脚信息</small>
  </footer>
</body>
</html>`;

  // 代码片段:HTML(卡片列表)
  const CARDS_HTML_SNIPPET = `<section class="cards-demo">
  <div class="cards">
    <article class="card">
      <header class="card-header">
        <h3 class="card-title">示例标题</h3>
      </header>
      <p class="card-desc">卡片描述文字……</p>
      <div class="card-tags">
        <span class="tag">标签</span>
      </div>
      <div class="card-actions">
        <button class="btn small">查看</button>
        <button class="btn small">收藏</button>
      </div>
    </article>
    <!-- 更多卡片… -->
  </div>
</section>`;

  // 代码片段:CSS(Grid/Flex)
  const GRID_CSS_SNIPPET = `/* 布局方案 A:Grid 栅格 */
.layout-grid .cards{ display:grid; grid-template-columns:1fr; gap:16px; }
/* SM ≥ 640px:两列 */
@media (min-width: 640px){ .layout-grid .cards{ grid-template-columns: repeat(2, 1fr); } }
/* MD ≥ 960px:三列 */
@media (min-width: 960px){ .layout-grid .cards{ grid-template-columns: repeat(3, 1fr); } }`;

  const FLEX_CSS_SNIPPET = `/* 布局方案 B:Flex 弹性 */
.layout-flex .cards{ display:flex; flex-wrap:wrap; gap:16px; }
.layout-flex .card{ width:100%; }
/* SM ≥ 640px:两列 */
@media (min-width: 640px){ .layout-flex .card{ width: calc(50% - 8px); } }
/* MD ≥ 960px:三列 */
@media (min-width: 960px){ .layout-flex .card{ width: calc(33.333% - 10.7px); } }`;

  // 菜单折叠
  const menuToggle = qs('#menuToggle');
  const siteNav = qs('#siteNav');
  menuToggle?.addEventListener('click', ()=>{
    const opened = siteNav.classList.toggle('open');
    menuToggle.setAttribute('aria-expanded', opened ? 'true' : 'false');
  });

  // 一键生成标准化结构
  const structurePreview = qs('#structurePreview');
  const generateStructureBtn = qs('#generateStructureBtn');
  generateStructureBtn?.addEventListener('click', ()=>{
    structurePreview.innerHTML = `
      <div class="structure-box">
        <h3>标准化结构(预览 + 可复制)</h3>
        <p class="muted">包含导航、主视觉、内容区、页脚与跳转主内容链接。</p>
        <pre class="code-block"><code>${escapeHtml(STANDARD_STRUCTURE_HTML)}</code></pre>
        <button class="btn small" id="copyStructureBtn">复制结构代码</button>
      </div>
    `;
    qs('#copyStructureBtn', structurePreview)?.addEventListener('click', ()=>{
      copyText(STANDARD_STRUCTURE_HTML);
      announce('标准化结构代码已复制');
    });
    setActiveTab('htmlSnippet');
    setSnippet('html', STANDARD_STRUCTURE_HTML);
    announce('标准化结构已生成并展示');
  });

  // 布局与示例数据渲染
  const cardContainer = qs('#cardContainer');
  const layoutWrapper = qs('#layoutWrapper');
  const resetDataBtn = qs('#resetDataBtn');

  function renderCards(){
    cardContainer.setAttribute('aria-busy', 'true');
    cardContainer.innerHTML = sampleItems.map(createCardHTML).join('');
    cardContainer.setAttribute('aria-busy', 'false');
  }

  function createCardHTML(item){
    const icon = `<svg width="36" height="36" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <rect x="1.5" y="1.5" width="33" height="33" rx="8" fill="#EEF6FF" stroke="#2B6CB0"/>
      <path d="M8 18h20M18 8v20" stroke="#2B6CB0" stroke-width="2"/>
    </svg>`;
    return `<article class="card">
      <header class="card-header">${icon}<h3 class="card-title">${escapeHtml(item.title)}</h3></header>
      <p class="card-desc">${escapeHtml(item.desc)}</p>
      <div class="card-tags">${item.tags.map(t => `<span class="tag">${escapeHtml(t)}</span>`).join('')}</div>
      <div class="card-actions">
        <button class="btn small" aria-label="查看 ${escapeHtml(item.title)}">查看</button>
        <button class="btn small" aria-label="收藏 ${escapeHtml(item.title)}">收藏</button>
      </div>
    </article>`;
  }

  resetDataBtn?.addEventListener('click', ()=>{
    renderCards();
    announce('示例数据已重置');
  });

  // 布局切换与代码片段
  const htmlBlock = qs('#htmlSnippet code');
  const cssBlock = qs('#cssSnippet code');
  const tabButtons = qsa('.tab-btn');
  const copySnippetBtn = qs('#copySnippetBtn');
  const showBreakpoints = qs('#showBreakpoints');
  const breakpointBar = qs('#breakpointBar');

  function setSnippet(type, content){
    if(type === 'html'){
      htmlBlock.textContent = content;
    }else if(type === 'css'){
      cssBlock.textContent = content;
    }
  }
  function setActiveTab(id){
    tabButtons.forEach(btn=>{
      const target = btn.dataset.target;
      const active = target === id;
      btn.classList.toggle('active', active);
      btn.setAttribute('aria-selected', active ? 'true' : 'false');
      qs('#'+target).classList.toggle('hidden', !active);
    });
  }
  tabButtons.forEach(btn=>{
    btn.addEventListener('click', ()=>{
      setActiveTab(btn.dataset.target);
    });
  });

  // 初始化:渲染卡片、默认布局与片段
  renderCards();
  setSnippet('html', CARDS_HTML_SNIPPET);
  setSnippet('css', GRID_CSS_SNIPPET);

  // 布局模式切换
  qsa('input[name="layoutMode"]').forEach(radio=>{
    radio.addEventListener('change', ()=>{
      const val = radio.value;
      layoutWrapper.classList.toggle('layout-grid', val === 'grid');
      layoutWrapper.classList.toggle('layout-flex', val === 'flex');
      setActiveTab('cssSnippet');
      setSnippet('css', val === 'grid' ? GRID_CSS_SNIPPET : FLEX_CSS_SNIPPET);
      announce(`布局已切换为 ${val === 'grid' ? 'Grid 栅格' : 'Flex 弹性'}`);
    });
  });

  // 断点辅助栏开关
  showBreakpoints?.addEventListener('change', ()=>{
    const on = showBreakpoints.checked;
    breakpointBar.style.display = on ? 'block' : 'none';
    announce(on ? '已显示断点辅助栏' : '已隐藏断点辅助栏');
  });

  // 复制当前片段
  copySnippetBtn?.addEventListener('click', ()=>{
    const active = tabButtons.find(btn=>btn.classList.contains('active'))?.dataset.target;
    const text = active === 'cssSnippet' ? cssBlock.textContent : htmlBlock.textContent;
    copyText(text);
    announce('代码片段已复制到剪贴板');
  });

  // 表单:字符计数与提交验证
  const form = qs('#assignmentForm');
  const desc = qs('#assignmentDesc');
  const descCount = qs('#descCount');
  const formErrors = qs('#formErrors');
  const submissionList = qs('#submissionList');
  const exportFormDataBtn = qs('#exportFormDataBtn');

  desc?.addEventListener('input', ()=>{
    descCount.textContent = `${desc.value.length} / ${desc.maxLength}`;
  });

  form?.addEventListener('submit', (e)=>{
    e.preventDefault();
    formErrors.style.display = 'none';
    if(!form.checkValidity()){
      showFormErrors();
      return;
    }
    const data = new FormData(form);
    const entry = {
      name: data.get('studentName')?.toString().trim(),
      email: data.get('studentEmail')?.toString().trim(),
      title: data.get('assignmentTitle')?.toString().trim(),
      link: data.get('assignmentLink')?.toString().trim(),
      desc: data.get('assignmentDesc')?.toString().trim(),
      ts: new Date().toISOString(),
      grade: null  // 待评分
    };
    addSubmission(entry);
    form.reset();
    descCount.textContent = `0 / ${desc.maxLength}`;
    announce('作业已提交,状态为待评分');
  });

  function showFormErrors(){
    const invalids = qsa('#assignmentForm input:invalid, #assignmentForm textarea:invalid');
    const names = invalids.map(el=> qs(`label[for="${el.id}"]`)?.textContent || el.name);
    formErrors.innerHTML = `<strong>请检查以下字段:</strong> ${names.join('、')}`;
    formErrors.style.display = 'block';
    invalids[0]?.focus();
    announce('表单校验失败,请完善必填项');
  }

  function addSubmission(entry){
    const li = document.createElement('li');
    li.className = 'submission-item';
    li.innerHTML = `
      <div>
        <strong>${escapeHtml(entry.title)}</strong>
        <div class="submission-meta">
          <span>${escapeHtml(entry.name)} · ${escapeHtml(entry.email)}</span>
          ${entry.link ? ` · <a href="${escapeAttr(entry.link)}" target="_blank" rel="noopener">作品链接</a>` : ''}
        </div>
      </div>
      <div class="grade-placeholder" role="status" aria-label="评分占位">待评分</div>
    `;
    submissionList.prepend(li);
  }

  // 导出表单数据
  exportFormDataBtn?.addEventListener('click', ()=>{
    const items = qsa('.submission-item').map(li=>{
      const title = li.querySelector('strong')?.textContent || '';
      const meta = li.querySelector('.submission-meta')?.textContent || '';
      const grade = li.querySelector('.grade-placeholder')?.textContent || '待评分';
      return { title, meta, grade };
    });
    downloadText(JSON.stringify({ exportedAt: new Date().toISOString(), submissions: items }, null, 2), 'submissions.json', 'application/json');
    announce('已导出提交列表数据');
  });

  // 导出讲义(Markdown)
  const exportHandoutBtn = qs('#exportHandoutBtn');
  exportHandoutBtn?.addEventListener('click', ()=>{
    const md = buildHandoutMarkdown();
    downloadText(md, '前端教学讲义.md', 'text/markdown');
    announce('讲义已导出');
  });

  // 导出代码与页面快照(自包含)
  const exportHTMLBtn = qs('#exportHTMLBtn');
  const exportCSSBtn = qs('#exportCSSBtn');
  const exportJSBtn = qs('#exportJSBtn');
  const exportSnapshotBtn = qs('#exportSnapshotBtn');

  exportHTMLBtn?.addEventListener('click', ()=>{
    downloadText(HTML_SOURCE, 'index.html', 'text/html');
    announce('HTML 源文件已导出');
  });
  exportCSSBtn?.addEventListener('click', ()=>{
    downloadText(CSS_SOURCE, 'styles.css', 'text/css');
    announce('CSS 源文件已导出');
  });
  exportJSBtn?.addEventListener('click', ()=>{
    downloadText(JS_SOURCE, 'script.js', 'text/javascript');
    announce('JS 源文件已导出');
  });
  exportSnapshotBtn?.addEventListener('click', ()=>{
    const snapshot = `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>页面快照</title><style>${CSS_SOURCE}</style></head><body>${document.body.outerHTML}<script>${JS_SOURCE}</script></body></html>`;
    downloadText(snapshot, 'snapshot.html', 'text/html');
    announce('已导出页面快照(内联CSS/JS)');
  });

  // 工具函数
  function escapeHtml(str=''){
    return str.replace(/[&<>"']/g, s=>({ '&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#39;' }[s]));
  }
  function escapeAttr(str=''){
    return str.replace(/"/g, '&quot;');
  }
  function copyText(text){
    if(navigator.clipboard && window.isSecureContext){
      navigator.clipboard.writeText(text).catch(()=>fallbackCopy(text));
    }else{
      fallbackCopy(text);
    }
  }
  function fallbackCopy(text){
    const ta = document.createElement('textarea');
    ta.value = text; document.body.appendChild(ta);
    ta.select(); try{ document.execCommand('copy'); }catch(e){}
    document.body.removeChild(ta);
  }
  function downloadText(text, filename, type='text/plain'){
    const blob = new Blob([text], {type});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a'); a.href = url; a.download = filename;
    document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
  }

  function buildHandoutMarkdown(){
    return [
      '# 前端教学讲义',
      '',
      '## 目标',
      '- 理解 HTML5 语义化结构(header/nav/main/section/footer)。',
      '- 掌握响应式布局(Grid 与 Flex)与断点设计。',
      '- 学会表单可访问性与基础校验,了解数据导出。',
      '',
      '## 标准化结构示例',
      '```html',
      STANDARD_STRUCTURE_HTML.replace(/```/g, '\\`\\`\\`'),
      '```',
      '',
      '## 布局片段(Grid)',
      '```css',
      GRID_CSS_SNIPPET,
      '```',
      '',
      '## 布局片段(Flex)',
      '```css',
      FLEX_CSS_SNIPPET,
      '```',
      '',
      '## 练习任务',
      '1. 在 Grid 布局下,调整列间距与卡片样式,使其更符合你的项目风格。',
      '2. 尝试将 Flex 方案改造为瀑布流或不等高卡片的均衡排列(提示:align-content、order)。',
      '3. 为作业表单增加更多校验规则(如标题长度、URL格式等),并在提交列表中显示部分字段。',
      '',
      '## 无障碍要点',
      '- 跳转主内容链接与可见焦点。',
      '- ARIA 属性:aria-live、aria-label、aria-controls、aria-expanded。',
      '- 表单标签与错误提示可被读屏识别。',
      '',
      '## 参考建议',
      '- 将断点命名与设计系统(Design Tokens)绑定,保持一致性。',
      '- 代码片段讲解与项目实践相结合,强化吸收。',
      '',
      '(本讲义由教学示例页自动生成)'
    ].join('\n');
  }

  // 以下三段源文件字符串用于“导出代码”按钮生成文件。
  // 为了演示的自包含导出功能,它们与当前页面的 HTML/CSS/JS 内容保持一致。
  const HTML_SOURCE = `<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <meta name="description" content="前端教学示例页:标准化结构、一键生成、布局切换、响应式断点、作业提交与导出讲义。">
  <title>前端教学示例页 · 标准化结构与响应式布局演示</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <a class="skip-link" href="#main">跳转到主内容</a>
  <header class="site-header" role="banner">
    <div class="container header-inner">
      <a class="brand" href="#" aria-label="网站品牌标识">教学示例页</a>
      <button id="menuToggle" class="menu-toggle" aria-expanded="false" aria-controls="siteNav">菜单</button>
      <nav id="siteNav" class="site-nav" aria-label="主导航">
        <ul>
          <li><a href="#hero">简介</a></li>
          <li><a href="#a11y">无障碍与语义化</a></li>
          <li><a href="#layout">布局演示</a></li>
          <li><a href="#codeDoc">代码讲解</a></li>
          <li><a href="#assignment">作业提交</a></li>
          <li><a href="#export">导出工具</a></li>
        </ul>
      </nav>
    </div>
  </header>
  <main id="main" tabindex="-1">
    <section id="hero" class="hero" aria-label="主视觉与快速操作">
      <div class="container hero-inner">
        <div class="hero-text">
          <h1>前端教学示例:结构、布局与交互</h1>
          <p>一键生成标准化页面结构,演示响应式栅格与断点注释,切换Grid / Flex布局方案,提供代码片段讲解与作业提交/导出工具。</p>
          <div class="hero-actions">
            <button id="generateStructureBtn" class="btn primary">一键生成标准化结构</button>
            <button id="exportHandoutBtn" class="btn">导出讲义(Markdown)</button>
          </div>
        </div>
        <div class="hero-art" aria-hidden="true">
          <svg width="220" height="140" viewBox="0 0 220 140" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="教学示意图">
            <rect x="5" y="5" width="210" height="130" rx="10" fill="#E6F0FF" stroke="#2B6CB0" stroke-width="2"/>
            <rect x="15" y="20" width="190" height="20" rx="4" fill="#CDE2FF"/>
            <rect x="15" y="50" width="90" height="70" rx="6" fill="#D9F2E6"/>
            <rect x="115" y="50" width="90" height="70" rx="6" fill="#FFEFD2"/>
            <text x="110" y="35" text-anchor="middle" font-size="12" fill="#2B6CB0">Nav / Hero / Grid / Footer</text>
          </svg>
        </div>
      </div>
      <div class="container">
        <div id="structurePreview" class="structure-preview" aria-live="polite" aria-atomic="true"></div>
      </div>
    </section>
    <section id="a11y" class="section">
      <div class="container">
        <h2>无障碍与语义化提示</h2>
        <ul class="a11y-list">
          <li>使用语义化标签:header、nav、main、section、article、footer。</li>
          <li>为交互控件添加可访问性属性:aria-label、aria-controls、aria-live、aria-expanded。</li>
          <li>提供“跳转主内容”链接,确保键盘导航与焦点可见。</li>
          <li>表单使用label显式关联输入框,错误提示与说明文本可被读屏识别。</li>
          <li>颜色对比充足,状态变化不只依赖颜色;提供可视化焦点样式。</li>
        </ul>
      </div>
    </section>
    <section id="layout" class="section">
      <div class="container">
        <div class="section-head">
          <h2>响应式布局演示(栅格与断点)</h2>
          <p>选择不同布局方案并查看代码片段与断点注释。栅格示例在小屏 1 列,中屏 2 列,大屏 3 列。</p>
        </div>
        <div class="controls" role="group" aria-label="布局切换控制">
          <div class="control-group">
            <span class="label">布局方案:</span>
            <label><input type="radio" name="layoutMode" value="grid" checked> Grid 栅格</label>
            <label><input type="radio" name="layoutMode" value="flex"> Flex 弹性</label>
          </div>
          <div class="control-group">
            <label><input type="checkbox" id="showBreakpoints"> 显示断点辅助栏</label>
          </div>
          <div class="control-group">
            <button id="resetDataBtn" class="btn">重置示例数据</button>
          </div>
        </div>
        <div id="breakpointBar" class="breakpoint-bar" aria-hidden="true">
          <div class="container">
            <strong>断点参考:</strong>
            <span>SM ≥ 640px</span>
            <span>MD ≥ 960px</span>
            <span>LG ≥ 1200px(容器最大宽度)</span>
          </div>
        </div>
        <div id="layoutWrapper" class="layout-wrapper layout-grid">
          <div id="cardContainer" class="cards" aria-live="polite" aria-busy="false"></div>
        </div>
      </div>
    </section>
    <section id="codeDoc" class="section">
      <div class="container">
        <div class="section-head">
          <h2>代码片段讲解</h2>
          <p>可复制 HTML / CSS 片段,配套注释,便于课堂讲解与自学复盘。</p>
        </div>
        <div class="code-tabs" role="tablist" aria-label="代码片段标签">
          <button class="tab-btn active" data-target="htmlSnippet" role="tab" aria-selected="true">HTML片段</button>
          <button class="tab-btn" data-target="cssSnippet" role="tab" aria-selected="false">CSS片段</button>
          <button id="copySnippetBtn" class="btn small">复制当前片段</button>
        </div>
        <div class="code-panels">
          <pre id="htmlSnippet" class="code-block" aria-label="HTML代码片段"><code></code></pre>
          <pre id="cssSnippet" class="code-block hidden" aria-label="CSS代码片段"><code></code></pre>
        </div>
      </div>
    </section>
    <section id="assignment" class="section">
      <div class="container">
        <h2>作业提交表单与评分占位</h2>
        <form id="assignmentForm" class="form" novalidate aria-labelledby="assignmentTitle">
          <div class="form-grid">
            <div class="form-item">
              <label for="studentName">姓名</label>
              <input id="studentName" name="studentName" type="text" required placeholder="例如:张三" aria-describedby="nameHelp">
              <small id="nameHelp" class="muted">使用真实姓名,便于确认成绩。</small>
            </div>
            <div class="form-item">
              <label for="studentEmail">邮箱</label>
              <input id="studentEmail" name="studentEmail" type="email" required placeholder="example@domain.com">
            </div>
            <div class="form-item">
              <label for="assignmentTitle">作业标题</label>
              <input id="assignmentTitle" name="assignmentTitle" type="text" required placeholder="响应式布局练习">
            </div>
            <div class="form-item">
              <label for="assignmentLink">作品链接</label>
              <input id="assignmentLink" name="assignmentLink" type="url" placeholder="https://example.com/demo" aria-describedby="linkHelp">
              <small id="linkHelp" class="muted">可填写在线预览地址或仓库链接。</small>
            </div>
            <div class="form-item">
              <label for="assignmentFile">上传文件(可选)</label>
              <input id="assignmentFile" name="assignmentFile" type="file" aria-describedby="fileHelp">
              <small id="fileHelp" class="muted">本地预览用,不会上传到服务器。</small>
            </div>
            <div class="form-item form-item--full">
              <label for="assignmentDesc">作业说明</label>
              <textarea id="assignmentDesc" name="assignmentDesc" rows="4" maxlength="500" placeholder="简要说明你的设计思路与实现细节…" aria-describedby="descCount"></textarea>
              <small id="descCount" class="muted" aria-live="polite">0 / 500</small>
            </div>
            <div class="form-item">
              <label><input id="agreePolicy" type="checkbox" required> 我已阅读并同意课堂提交规范</label>
            </div>
          </div>
          <div class="form-actions">
            <button type="submit" class="btn primary">提交作业</button>
            <button type="reset" class="btn">清空表单</button>
            <button type="button" id="exportFormDataBtn" class="btn">导出表单数据(JSON)</button>
          </div>
          <div id="formErrors" class="form-errors" aria-live="assertive"></div>
        </form>
        <div class="submissions">
          <h3>提交列表(评分占位)</h3>
          <ul id="submissionList" class="submission-list"></ul>
        </div>
      </div>
    </section>
    <section id="export" class="section">
      <div class="container">
        <h2>导出代码与讲义</h2>
        <p class="muted">可导出当前页面快照(内联CSS/JS),或分别导出HTML/CSS/JS源文件与课堂讲义。</p>
        <div class="export-actions">
          <button id="exportHTMLBtn" class="btn">导出 HTML</button>
          <button id="exportCSSBtn" class="btn">导出 CSS</button>
          <button id="exportJSBtn" class="btn">导出 JS</button>
          <button id="exportSnapshotBtn" class="btn">导出页面快照(自包含)</button>
        </div>
      </div>
    </section>
  </main>
  <footer class="site-footer" role="contentinfo">
    <div class="container footer-inner">
      <p>© 2025 教学示例页。用于教学演示,遵循 Web 标准与中国法律法规。</p>
      <nav aria-label="页脚导航"><a href="#hero">回到顶部</a></nav>
    </div>
  </footer>
  <div id="announce" class="sr-only" aria-live="polite" aria-atomic="true"></div>
  <script defer src="script.js"></script>
</body>
</html>`;

  const CSS_SOURCE = `/* 此处 CSS 内容与页面 styles.css 一致,详见本项目 CSS块 */\n` + document.querySelector('link[rel="stylesheet"]') ? '' : ''; // 占位(在线快照会内联真实CSS)

  // 由于当前环境无法直接读取外部CSS文件,这里提供教学占位:
  // 实际使用时,导出按钮会生成空CSS(请用上方“CSS样式”块内容保存为 styles.css)
  // 如果您将本页面的 CSS 内联进快照,snapshot 导出中将包含完整样式。

  const JS_SOURCE = `/* 此处 JS 内容与页面 script.js 一致,详见本项目 JS块 */\n` + (function(){return ''})();

  // 提示:为避免浏览器安全限制,这里不从外部 CSS/JS 文件读取。
  // 教学建议:请将“CSS样式”与“JavaScript功能”块分别保存为 styles.css 与 script.js。
  // 导出 HTML 按钮会生成一个 index.html,其 <link rel="stylesheet"> 与 <script src> 指向上述文件。

})(); 
```

说明:出于浏览器安全限制,脚本中无法直接读取外部 styles.css/script.js 的内容,因此 JS 中的 CSS_SOURCE/JS_SOURCE使用占位。请使用下方“使用说明”将本页 CSS 和 JS分别保存为文件后,本页的导出按钮即可生成指向这些文件的 HTML;“导出页面快照(自包含)”会将当前页面的 DOM、CSS 与 JS内联打包(在真实运行环境中,可将 CSS_SOURCE/JS_SOURCE替换为真实内容或由构建工具注入)。

---

## 使用说明
- 开发与运行
  1. 新建项目文件夹并创建以下文件:
     - index.html(使用“HTML代码”块内容)
     - styles.css(使用“CSS样式”块内容)
     - script.js(使用“JavaScript功能”块内容)
  2. 双击打开 index.html 即可在浏览器中查看,无需任何外部依赖。

- 教学演示流程建议
  1. 打开页面后,点击“一键生成标准化结构”,查看标准化HTML结构预览与复制。
  2. 在“布局演示”区切换 Grid/Flex,并勾选“显示断点辅助栏”,观察卡片列数变化和断点说明。
  3. 在“代码片段讲解”区切换 HTML/CSS片段,点击“复制当前片段”用于课堂讲解。
  4. 在“作业提交表单”中填写示例数据并提交,可在下方列表中看到“待评分”占位。
  5. 使用“导出工具”导出 HTML/CSS/JS、讲义(Markdown)或页面快照(自包含)。

- 浏览器兼容性
  - 现代浏览器(Chrome、Edge、Firefox、Safari)均可正常运行。
  - 移动端兼容,窄屏下导航折叠、表单单列显示。

- 无障碍与安全
  - 提供可见焦点与ARIA播报,表单有基础校验。
  - 不使用任何外部脚本资源或不安全API,避免安全风险。

---

## 定制建议
- 视觉主题
  - 将CSS变量(颜色、圆角、阴影)替换为企业品牌色与设计体系(Design Tokens)。
  - 为Hero区加入产品Logo或插画(建议使用内联SVG或本地资源)。

- 布局扩展
  - 在Grid方案中引入更复杂的布局,如区域网格(grid-template-areas)与不等列宽。
  - 在Flex方案中演示主轴/侧轴对齐、不同顺序(order)与响应式断点组合。

- 交互增强
  - 为卡片“查看/收藏”加入真实行为,如打开详情面板或本地存储收藏状态。
  - 增加“评分占位”交互组件(仅本地)、提交后可编辑备注与打分(避免实际上传)。

- 教学导出
  - 使用构建脚手架(如Vite)在开发时注入CSS/JS源到导出函数,生成完整快照与示例代码包。
  - 增加“讲义模版配置”,让教师可自定义章节与练习题目。

- 无障碍深度优化
  - 为所有按钮与链接提供更详细的 aria-label。
  - 加入颜色对比切换(高对比模式)与字体大小控制,提升可访问性体验。

如需我将导出功能改为打包ZIP或将CSS/JS真实内联到导出快照,请告知您的运行环境与限制(本地/服务器/构建工具),我将提供相应方案。

适用用户

创业团队与产品经理

用它快速搭建MVP展示页与功能说明页,收集报名或反馈,随时调整模块与风格,缩短验证周期并加速市场测试。

中小企业市场与运营

无需外包即可生成企业官网与活动落地页,保持品牌视觉一致,快速添加表单与轮播,促成线索收集与转化。

前端初学者与培训讲师

课堂或训练营中一键生成标准化页面,讲解页面结构与响应式布局,布置作业与示例,提高教学效率与学习成效。

解决的问题

将“前端网站全栈生成器”打造成你的即用型网站搭建助理:只需输入网站类型、设计风格与功能需求,即可一次性生成可上线的页面(含HTML、CSS、JavaScript),自动适配移动与桌面端,满足企业官网、活动落地页、作品集与教学演示等场景。核心目标是显著缩短从想法到成品的周期、降低沟通与外包成本、保障代码质量与后续扩展,让用户从首次试用迅速感知效率红利,并通过解锁高级能力实现持续付费。

特征总结

智能理解网站类型与风格,按需生成可立即上线的整站页面代码与结构,减少手工搭建时间
自动构建响应式布局,移动端与桌面端自适应呈现,无需额外调试,保证跨设备体验一致
内置常见业务模块如导航、页脚、表单与轮播,一键添加即用,显著减少重复搭建工作
支持多种设计风格与交互效果,快速切换主题,保证品牌视觉统一与活动页面高效落地
生成结构清晰、语义准确的代码,并预留充分定制空间,后续扩展与团队协作更顺畅
按需求加入必要交互逻辑,表单校验、弹窗与滚动动画等即可调用,显著提升页面体验
提供部署使用说明与定制建议,新手可迅速上手,资深开发可在此基础进行快速迭代
内置基本安全与规范考量,避免不当脚本与过时写法,降低上线风险与长期维护成本
适配快速原型与教学演示场景,分钟级产出可展示版本,助力评审决策与培训实操

如何使用购买的提示词模板

1. 直接在外部 Chat 应用中使用

将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

2. 发布为 API 接口调用

把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

3. 在 MCP Client 中配置使用

在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

¥20.00元
平台提供免费试用机制,
确保效果符合预期,再付费购买!

您购买后可以获得什么

获得完整提示词模板
- 共 722 tokens
- 3 个可调节参数
{ 网站类型 } { 设计风格 } { 功能需求 }
自动加入"我的提示词库"
- 获得提示词优化器支持
- 版本化管理支持
获得社区共享的应用案例
限时免费

不要错过!

免费获取高级提示词-优惠即将到期

17
:
23
小时
:
59
分钟
:
59