#import "theme.typ": * #import "config.typ": * // ===================================================================== // GreLin 求职简历 · Layout(Tailwind 灰稿) // 双栏共用 grid:右栏联系方式与下方模块左对齐 // ===================================================================== #let sidebar-photo() = { let path = profile.at("photo-path", default: "") if path != "" { block(width: 100%, below: space-photo-below)[ #box(width: 100%, clip: true, radius: rounded)[ #image(path, width: 100%, fit: "cover") ] ] } } #let profile-block() = block(width: 100%)[ #text(font: heading-font, size: size-name, weight: weight-semibold, fill: color-accent)[#profile.name] #v(space-name-summary) #box(width: summary-max-width)[ #set text(fill: color-text-light, size: size-prose, weight: weight-normal) #set par(leading: leading-prose, spacing: space-none, justify: false) #profile.summary ] ] #let sidebar-body(content) = { set text(fill: color-text-light, size: size-prose, weight: weight-normal) set par(leading: leading-prose, spacing: space-none, justify: false) content } #let sidebar-body-en(content) = sidebar-body(content) #let sidebar-body-zh(content) = sidebar-body(content) #let contact-block() = block(width: 100%)[ #let github = contact.at("github", default: "") #let github-label = contact.at("github-label", default: github) #set text(font: mono-font, size: size-prose, fill: color-meta, weight: weight-normal) #set par(leading: leading-prose, spacing: space-contact-line) #link("mailto:" + contact.email, contact.email) #linebreak() #link("tel:" + contact.phone, contact.phone) #if github != "" [ #linebreak() #link(github, github-label) ] #if contact.website != "" [ #linebreak() #link(contact.website, contact.website-label) ] ] #let section-title(title, above: auto, below: auto, accent: true) = { let gap-above = if above != auto { above } else { space-section } let gap-below = if below != auto { below } else { space-title-below } let title-color = if accent { color-accent } else { color-heading } block(width: 100%, above: gap-above, below: gap-below)[ #text(font: heading-font, size: size-section, weight: weight-semibold, fill: title-color)[#title] ] } #let sidebar-subtitle(title, above: auto, below: auto) = { let gap-above = if above != auto { above } else { space-skill-group } let gap-below = if below != auto { below } else { space-subtitle-below } block(above: gap-above, below: gap-below)[ #text(font: heading-font, size: size-body, weight: weight-semibold, fill: color-heading)[#title] ] } #let sidebar-entry-title(title) = block(below: space-subtitle-below)[ #text(font: heading-font, size: size-body, weight: weight-semibold, fill: color-heading)[#title] ] #let experience-entry(entry) = block[ #text(font: heading-font, size: size-body, fill: color-heading)[ #entry.role #text(fill: color-text-light, weight: weight-normal)[ · ] #text(weight: weight-semibold)[#entry.company] #h(space-entry-date-gap) #text(font: mono-font, fill: color-meta, size: size-body, weight: weight-normal)[ #entry.start#if entry.end != "" [ — #entry.end] ] ] #v(space-entry-title-below) #set text(fill: color-text-light, size: size-prose, weight: weight-normal) #set par(leading: leading-prose, spacing: space-none, justify: false) #set list(tight: true, indent: list-indent, body-indent: list-body-indent) #for line in entry.bullets [ - #line ] ] #let experiences-block() = { for (i, entry) in experiences.enumerate() { if i > 0 { v(space-entry) } experience-entry(entry) } } #let skills-block() = { for (i, cat) in skills.categories.enumerate() { sidebar-subtitle(cat.title, above: if i == 0 { space-none } else { space-subtitle-group }) block(below: space-none)[ #sidebar-body-en[#cat.items] ] } } #let sidebar-project-entry(entry) = block[ #sidebar-entry-title(entry.name) #sidebar-body-zh[#entry.intro] ] #let sidebar-projects-block() = { for (i, entry) in projects.enumerate() { if i > 0 { v(space-sidebar-item) } sidebar-project-entry(entry) } } #let sidebar-edu-entry(item) = block[ #sidebar-entry-title(item.school) #sidebar-body-zh[ #item.degree#if item.period != "" [ · #item.period] ] ] #let sidebar-education-block() = { for (i, item) in education.enumerate() { if i > 0 { v(space-sidebar-item) } sidebar-edu-entry(item) } } #let interests-block() = { if interests != "" { block(above: space-none)[ #sidebar-body-zh[#interests] ] } }