/** * ============================================================================= * Resume — 样式表 * ============================================================================= * * 文件结构: * 1. Reset & CSS 变量 (默认值) * 2. @media print — 打印样式(隐藏UI、多页分页、sidebar转顶部) * 3. @media screen — 屏幕端基础布局 * 4. Editable — contenteditable 交互样式 * 5. Grid Layout — 双栏布局 * 6. Typography — 标题、段落、字体 * 7. Sidebar — 侧边栏(联系方式、技能、教育) * 8. Sidebar Custom Sections — 动态自定义栏目 * 9. Main Content — 主内容区 * 10. Section Cards — 经历/项目卡片 * 11. Bullet Lists — 要点列表 * 12. Add Buttons — 添加按钮 * 13. Toolbar — 顶部工具栏 * 14. DESIGN THEMES — 12 套版式布局(.page.theme-xxx) * 15. Responsive — 移动端适配 * * 颜色不在本文件中硬编码;全部通过 CSS 变量控制,由 app.js 动态注入。 * 设计主题通过 .page 上的 CSS class 切换(如 .page.theme-timeline)。 * ============================================================================= */ /* ===== Reset & Variables ===== */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --ink: #1a1a1a; --ink-muted: #555; --accent: #1e5fa8; --accent-light: #e8f0fa; --border: #ddd; --bg: #fff; --surface: #f8f9fa; --radius: 6px; --font-sans: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", system-ui, -apple-system, sans-serif; --font-mono: "JetBrains Mono", "Cascadia Code", "Fira Code", "SF Mono", "Monaco", monospace; } /* ===== Print ===== */ @media print { @page { size: A4; margin: 0; } body { background: #fff; -webkit-print-color-adjust: exact; print-color-adjust: exact; } .page { box-shadow: none; margin: 0 auto; padding: 36px 44px; max-width: 210mm; /* No min-height — natural multi-page flow */ } .section-card { break-inside: avoid; page-break-inside: avoid; } h2 { break-after: avoid; page-break-after: avoid; } /* Keep heading with the first card that follows */ section > h2 + * { break-before: avoid; } .no-print { display: none !important; } [contenteditable]:focus { outline: none; } [contenteditable]:empty::before { display: none; } /* Collapse sidebar into compact header on page 1; page 2+ is full-width main */ .resume-grid { grid-template-columns: 1fr; gap: 0; } .sidebar { position: static; display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: flex-start; padding-bottom: 14px; margin-bottom: 20px; border-bottom: 2px solid var(--accent); } .sidebar .name-section { flex-basis: 100%; margin-bottom: 4px; } .sidebar .name-section h1 { font-size: 22px; display: flex; gap: 12px; align-items: baseline; } .sidebar .name-section h1 .sub { margin-top: 0; } .sidebar section { margin-bottom: 0; min-width: 120px; } .sidebar h2 { border-bottom: none; margin-bottom: 2px; padding-bottom: 0; font-size: 11px; } .sidebar .info-item { margin-bottom: 1px; } .skill-tags { gap: 3px; } .skill-tag { font-size: 10px; padding: 1px 5px; } .editable-block h3 { font-size: 12px; } .sidebar .section-sub { font-size: 11px; } .sidebar .date { font-size: 11px; } /* Sidebar custom sections in print */ .sidebar-custom-section { min-width: 100px; } .sidebar-custom-section h2 { font-size: 11px; margin-bottom: 2px; } .sidebar-custom-section .sidebar-custom-content { font-size: 11px; } /* Main content full width */ .main { width: 100%; } } /* ===== Screen ===== */ @media screen { body { background: var(--body-bg, #e8ecf1); font-family: var(--font-sans); color: var(--ink); line-height: 1.6; padding: 20px; min-height: 100vh; display: flex; flex-direction: column; align-items: center; } .page { background: var(--bg); width: 210mm; min-height: 297mm; padding: 36px 44px; box-shadow: 0 2px 20px rgba(0,0,0,.12); position: relative; } } /* ===== Editable ===== */ [contenteditable] { outline: none; border-radius: 3px; transition: background .15s; cursor: text; } [contenteditable]:hover { background: rgba(30,95,168,.04); } [contenteditable]:focus { background: rgba(30,95,168,.08); box-shadow: 0 0 0 1.5px var(--accent); border-radius: 3px; } [contenteditable]:empty::before { content: attr(data-placeholder); color: #bbb; font-style: italic; } /* ===== Layout ===== */ .resume-grid { display: grid; grid-template-columns: 180px 1fr; gap: 32px; align-items: start; } .sidebar { position: sticky; top: 36px; } /* ===== Typography ===== */ h1 { font-size: 26px; font-weight: 700; letter-spacing: 1px; line-height: 1.2; margin-bottom: 4px; } h1 .sub { display: block; font-size: 13px; font-weight: 400; color: var(--ink-muted); margin-top: 4px; letter-spacing: 0; } h2 { font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; color: var(--accent); margin-bottom: 10px; padding-bottom: 5px; border-bottom: 2px solid var(--accent); } h3 { font-size: 14px; font-weight: 600; margin-bottom: 2px; } h3 .meta { font-weight: 400; color: var(--ink-muted); font-size: 12px; } /* ===== Sidebar ===== */ .sidebar section { margin-bottom: 22px; } .sidebar h2 { border-bottom-color: var(--border); color: var(--ink); font-size: 12px; } .name-section { margin-bottom: 18px; } .info-item { font-size: 12px; margin-bottom: 5px; display: flex; gap: 5px; } .info-label { color: var(--ink-muted); flex-shrink: 0; } .skill-tags { display: flex; flex-wrap: wrap; gap: 5px; } .skill-tag { font-size: 11px; background: var(--accent-light); color: var(--accent); padding: 2px 8px; border-radius: 3px; font-weight: 500; position: relative; cursor: text; } .skill-tag .tag-delete { display: none; position: absolute; top: -6px; right: -6px; width: 16px; height: 16px; background: #e74c3c; color: #fff; border-radius: 50%; font-size: 10px; line-height: 16px; text-align: center; cursor: pointer; border: none; } .skill-tag:hover .tag-delete { display: block; } /* ===== Sidebar custom sections ===== */ .sidebar-custom-section { margin-bottom: 16px; position: relative; padding: 8px; border: 1px dashed transparent; border-radius: var(--radius); transition: border-color .15s; } .sidebar-custom-section:hover { border-color: var(--border); } .sidebar-custom-section .sidebar-custom-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.5px; color: var(--ink); margin-bottom: 4px; padding-bottom: 4px; border-bottom: 1.5px solid var(--border); min-width: 2em; } .sidebar-custom-section .sidebar-custom-content { font-size: 12px; color: var(--ink-muted); line-height: 1.5; min-height: 1em; } .sidebar-custom-section .card-delete { display: none; position: absolute; top: -4px; right: -4px; width: 18px; height: 18px; background: #e74c3c; color: #fff; border: none; border-radius: 50%; font-size: 10px; line-height: 18px; text-align: center; cursor: pointer; opacity: .7; } .sidebar-custom-section:hover .card-delete { display: block; } /* ===== Main ===== */ .main section { margin-bottom: 24px; } /* Section card (experience, project) */ .section-card { position: relative; margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px dashed var(--border); } .section-card:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .section-card .card-delete { display: none; position: absolute; top: 0; right: 0; width: 22px; height: 22px; background: #e74c3c; color: #fff; border: none; border-radius: 50%; font-size: 12px; line-height: 22px; text-align: center; cursor: pointer; opacity: .7; transition: opacity .15s; } .section-card:hover .card-delete { display: block; } .section-card .card-delete:hover { opacity: 1; } .section-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 2px; } .section-header .date { font-size: 12px; color: var(--ink-muted); white-space: nowrap; margin-left: 10px; } .section-sub { font-size: 13px; color: var(--ink-muted); margin-bottom: 6px; } /* Bullet list */ ul.bullets { list-style: none; padding: 0; } ul.bullets li { font-size: 13px; margin-bottom: 3px; padding-left: 14px; position: relative; } ul.bullets li::before { content: "—"; position: absolute; left: 0; color: var(--accent); font-weight: 700; } p { font-size: 13px; margin-bottom: 4px; } .date { font-size: 12px; color: var(--ink-muted); } /* ===== Add Button ===== */ .add-btn-group { margin-top: 8px; } .add-btn { font-size: 12px; padding: 4px 12px; border: 1px dashed var(--accent); background: transparent; color: var(--accent); border-radius: var(--radius); cursor: pointer; font-family: var(--font-sans); transition: all .15s; } .add-btn:hover { background: var(--accent-light); border-style: solid; } /* ===== Toolbar ===== */ .toolbar { position: fixed; top: 14px; right: 14px; display: flex; gap: 8px; z-index: 100; } .btn { font-size: 12px; padding: 7px 14px; border: none; border-radius: var(--radius); cursor: pointer; font-weight: 600; transition: all .15s; font-family: var(--font-sans); } .btn-print { background: var(--accent); color: #fff; } .btn-print:hover { background: #164a85; } .btn-xml { background: #fff; color: var(--accent); border: 1px solid var(--accent); } .btn-xml:hover { background: var(--accent-light); } .theme-switcher { display: flex; align-items: center; gap: 2px; } .btn-theme { background: transparent; color: var(--ink-muted); border: 1px solid var(--border); padding: 5px 8px; font-size: 11px; min-width: auto; } .btn-theme:hover { background: var(--surface); color: var(--ink); } .theme-label { font-size: 11px; color: var(--accent); font-weight: 600; min-width: 48px; text-align: center; user-select: none; } .btn-reset { background: #fff; color: var(--ink-muted); border: 1px solid var(--border); } .btn-reset:hover { background: var(--surface); } .edit-hint { position: fixed; bottom: 14px; left: 50%; transform: translateX(-50%); font-size: 12px; background: rgba(0,0,0,.7); color: #fff; padding: 5px 16px; border-radius: 20px; z-index: 100; pointer-events: none; } /* ===== Editable block ===== */ .editable-block { position: relative; } /* ===== Summary ===== */ .summary-text { min-height: 1.6em; } /* ===== Bullet list item controls ===== */ .bullet-li { display: flex; align-items: flex-start; gap: 4px; margin-bottom: 3px; } .bullet-li .li-delete { display: none; flex-shrink: 0; width: 16px; height: 16px; background: #e74c3c; color: #fff; border: none; border-radius: 50%; font-size: 10px; line-height: 16px; text-align: center; cursor: pointer; opacity: .7; margin-top: 2px; } .bullet-li:hover .li-delete { display: block; } /* ===== Responsive ===== */ @media screen and (max-width: 800px) { .page { width: 100%; padding: 20px 16px; } .resume-grid { grid-template-columns: 1fr; gap: 20px; } .sidebar { position: static; } .toolbar { top: 6px; right: 6px; } .btn { padding: 5px 10px; font-size: 11px; } } /* ============================================================ DESIGN THEMES — 12 layout presets Applied via .page.theme-xxx ============================================================ */ /* 1. Classic — default, no overrides needed */ /* 2. Minimal — single column, sidebar as compact top header */ .page.theme-minimal .resume-grid { grid-template-columns: 1fr; gap: 24px; } .page.theme-minimal .sidebar { position: static; display: flex; flex-wrap: wrap; gap: 6px 24px; align-items: flex-start; padding-bottom: 12px; margin-bottom: 18px; border-bottom: 2px solid var(--border); } .page.theme-minimal .sidebar .name-section { flex-basis: 100%; margin-bottom: 2px; } .page.theme-minimal .sidebar .name-section h1 { font-size: 24px; } .page.theme-minimal .sidebar section { margin-bottom: 0; min-width: 100px; } .page.theme-minimal .sidebar h2 { border-bottom: none; margin-bottom: 2px; padding-bottom: 0; font-size: 11px; } /* 3. Right bar — sidebar on the right */ .page.theme-rightbar .resume-grid { grid-template-columns: 1fr 180px; } .page.theme-rightbar .sidebar { order: 2; } /* 4. Top bar — sidebar as full-width header, single column body */ .page.theme-topbar .resume-grid { grid-template-columns: 1fr; gap: 0; } .page.theme-topbar .sidebar { position: static; display: flex; flex-wrap: wrap; gap: 6px 28px; align-items: flex-start; padding-bottom: 14px; margin-bottom: 22px; border-bottom: 2px solid var(--accent); } .page.theme-topbar .sidebar .name-section { flex-basis: 100%; margin-bottom: 4px; } .page.theme-topbar .sidebar .name-section h1 { font-size: 24px; } .page.theme-topbar .sidebar section { margin-bottom: 0; min-width: 100px; } .page.theme-topbar .sidebar h2 { border-bottom: none; margin-bottom: 2px; padding-bottom: 0; font-size: 11px; } /* 5. Accent bar — thick accent left border on sidebar */ .page.theme-accentbar .sidebar { border-left: 4px solid var(--accent); padding-left: 14px; } /* 6. Wide side — 240px sidebar */ .page.theme-wideside .resume-grid { grid-template-columns: 240px 1fr; } /* 7. Compact — tighter spacing everywhere */ .page.theme-compact .resume-grid { gap: 20px; } .page.theme-compact .sidebar section { margin-bottom: 14px; } .page.theme-compact .main section { margin-bottom: 16px; } .page.theme-compact .section-card { margin-bottom: 8px; padding-bottom: 8px; } .page.theme-compact h1 { font-size: 22px; } .page.theme-compact h2 { font-size: 12px; margin-bottom: 6px; padding-bottom: 3px; } .page.theme-compact h3 { font-size: 12px; } .page.theme-compact ul.bullets li { font-size: 11px; margin-bottom: 1px; } .page.theme-compact p { font-size: 11px; } .page.theme-compact .page { padding: 28px 32px; } /* 8. Cards — sections wrapped in card containers */ .page.theme-cards .main section { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; margin-bottom: 16px; } .page.theme-cards .main section h2 { margin-top: -4px; } /* 9. Timeline — left-positioned date markers on experiences/projects */ .page.theme-timeline .section-card { padding-left: 80px; position: relative; } .page.theme-timeline .section-card .date { position: absolute; left: 0; top: 0; font-size: 11px; color: var(--accent); font-weight: 600; white-space: nowrap; } .page.theme-timeline .section-card::before { content: ''; position: absolute; left: 68px; top: 4px; width: 6px; height: 6px; background: var(--accent); border-radius: 50%; } .page.theme-timeline .section-header .date { display: none; } /* 10. Duotone — sidebar has a subtle background colour */ .page.theme-duotone .sidebar { background: var(--surface); margin: -16px; padding: 16px; border-radius: var(--radius); } .page.theme-duotone .resume-grid { gap: 28px; } /* 11. Lines — bold horizontal rules between sections, no card borders */ .page.theme-lines .main section { padding-bottom: 18px; margin-bottom: 18px; border-bottom: 2px solid var(--accent); } .page.theme-lines .main section:last-child { border-bottom: none; } .page.theme-lines .section-card { border-bottom: 1px solid var(--border); } .page.theme-lines .section-card:last-child { border-bottom: none; } .page.theme-lines .sidebar section { padding-bottom: 14px; border-bottom: 1px solid var(--border); } .page.theme-lines .sidebar section:last-child { border-bottom: none; } /* 12. Frameless — no borders, no backgrounds, pure whitespace */ .page.theme-frameless .sidebar h2 { border-bottom: none; padding-bottom: 0; } .page.theme-frameless .main section h2 { border-bottom: none; padding-bottom: 0; } .page.theme-frameless .section-card { border-bottom: none; padding-bottom: 10px; margin-bottom: 10px; } .page.theme-frameless .sidebar-custom-section { border: none; } .page.theme-frameless .sidebar-custom-section .sidebar-custom-title { border-bottom: none; } .page.theme-frameless .add-btn { border-style: solid; opacity: .5; }