diff --git a/public/img/audit.png b/public/img/audit.png index ded1e24..198687b 100644 Binary files a/public/img/audit.png and b/public/img/audit.png differ diff --git a/public/img/document_generation.png b/public/img/document_generation.png new file mode 100644 index 0000000..5f4c3b7 Binary files /dev/null and b/public/img/document_generation.png differ diff --git a/public/img/redactions.png b/public/img/redactions.png index 1a78805..080ab51 100644 Binary files a/public/img/redactions.png and b/public/img/redactions.png differ diff --git a/public/img/robot_arm.png b/public/img/robot_arm.png index 91f4478..ff8d05c 100644 Binary files a/public/img/robot_arm.png and b/public/img/robot_arm.png differ diff --git a/src/app/app.css b/src/app/app.css index bdb49b7..131533a 100644 --- a/src/app/app.css +++ b/src/app/app.css @@ -40,7 +40,7 @@ color: #ffb57e; font-size: 14px; font-weight: 700; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; padding: 6px 16px; border-radius: 20px; width: fit-content; @@ -49,8 +49,8 @@ } .hero-title { - font-family: 'Google Sans Text', sans-serif; - font-size: 50px; + font-family: sans-serif; + font-size: 70px; font-weight: 700; line-height: 1.1; color: var(--mat-sys-onSurface); @@ -59,7 +59,7 @@ } .hero-subtitle { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 30px; color: var(--mat-sys-onSurface); margin: 0 0 8px; @@ -80,7 +80,7 @@ border-radius: 50px; font-size: 22px; font-weight: 500; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; text-decoration: none; transition: all 0.2s ease; letter-spacing: 0.3px; @@ -133,7 +133,7 @@ } .section-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 36px; font-weight: 700; color: var(--mat-sys-onSurface); @@ -144,7 +144,7 @@ .section-desc { font-size: 28px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; margin: 0; } @@ -169,7 +169,7 @@ text-align: center; font-size: 28px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; margin: 0 0 48px; line-height: 1.7; max-width: 800px; @@ -206,7 +206,7 @@ } .competency-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 28px; font-weight: 700; color: var(--mat-sys-onSurface); @@ -216,7 +216,7 @@ .competency-desc { font-size: 22px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; line-height: 1.7; margin: 0; } @@ -249,7 +249,7 @@ .mde-tabs .tab-label{ font-size: 18px !important; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; font-weight: 600; } @@ -270,7 +270,7 @@ We must set it explicitly. */ .mde-tabs .mdc-tab__text-label { color: var(--mat-sys-onSurfaceVariant) !important; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; font-size: 18px !important; font-weight: 500 !important; letter-spacing: 0.2px !important; @@ -279,7 +279,7 @@ .mde-tabs .mdc-tab--active .mdc-tab__text-label { color: #ff8c3e !important; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; font-size: 18px !important; } @@ -333,7 +333,7 @@ } .project-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 28px; font-weight: 600; color: var(--mat-sys-onSurface); @@ -347,7 +347,7 @@ padding: 4px 12px; border-radius: 12px; white-space: nowrap; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } .status-done { @@ -370,7 +370,7 @@ line-height: 1.6; color: var(--mat-sys-onSurfaceVariant); margin: 0 0 16px; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } .project-meta { @@ -386,7 +386,7 @@ gap: 6px; font-size: 13px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } .project-meta-icon { @@ -411,14 +411,14 @@ padding: 4px 12px; border-radius: 8px; letter-spacing: 0.3px; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } .tech-badge-outline { background: transparent; color: var(--mat-sys-onSurfaceVariant); border: 1px solid rgba(255, 255, 255, 0.1); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } /* ============================== @@ -455,7 +455,7 @@ } .success-story-card-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 28px; font-weight: 600; color: var(--mat-sys-onSurface); @@ -473,7 +473,7 @@ } .success-story-card-desc { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 20px; line-height: 1.6; color: var(--mat-sys-onSurfaceVariant); @@ -525,7 +525,7 @@ } .quality-card-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 28px; font-weight: 600; color: var(--mat-sys-onSurface); @@ -537,7 +537,7 @@ line-height: 1.6; color: var(--mat-sys-onSurfaceVariant); margin: 0; - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; margin-left: 28px; margin-right: 28px; width: 500px; @@ -595,7 +595,7 @@ } .repo-name { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 32px !important; font-weight: 600; color: var(--mat-sys-onSurface); @@ -610,7 +610,7 @@ padding: 3px 10px; border-radius: 10px; white-space: nowrap; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; } .repo-desc { @@ -618,7 +618,7 @@ line-height: 1.6; color: var(--mat-sys-onSurfaceVariant); margin: 0; - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; } .repo-actions { @@ -634,7 +634,7 @@ font-size: 20px; font-weight: 500; color: #ff8c3e; - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; text-decoration: none; transition: color 0.15s ease; } @@ -666,7 +666,7 @@ } .contact-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 36px; font-weight: 700; color: var(--mat-sys-onSurface); @@ -677,7 +677,7 @@ .contact-desc { font-size: 28px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; margin: 0 0 48px; line-height: 1.6; } @@ -703,7 +703,7 @@ border-radius: 12px; font-size: 16px; color: var(--mat-sys-onSurface); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; outline: none; transition: border-color 0.2s ease, box-shadow 0.2s ease; box-sizing: border-box; @@ -733,7 +733,7 @@ color: #000000; font-size: 16px; font-weight: 600; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; border: none; border-radius: 50px; cursor: pointer; @@ -793,7 +793,7 @@ } .person-name { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 28px; font-weight: 700; color: var(--mat-sys-onSurface); @@ -803,7 +803,7 @@ .person-role { font-size: 18px; color: #ff8c3e; - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; font-weight: 500; margin: 0 0 16px; } @@ -812,7 +812,7 @@ font-size: 20px; line-height: 1.7; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; text-align: center; margin: 0 0 28px; } @@ -828,7 +828,7 @@ gap: 6px; font-size: 14px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; text-decoration: none; transition: color 0.15s ease; } @@ -873,7 +873,7 @@ } .footer-title { - font-family: 'Google Sans Text', sans-serif; + font-family: 'Google Sans', sans-serif; font-size: 24px; font-weight: 700; color: var(--mat-sys-onSurface); @@ -883,7 +883,7 @@ .footer-tagline { font-size: 14px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; margin: 0; } @@ -897,7 +897,7 @@ .footer-link { font-size: 14px; color: var(--mat-sys-onSurfaceVariant); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; text-decoration: none; transition: color 0.15s ease; } @@ -909,7 +909,7 @@ .footer-copy { font-size: 13px; color: var(--mat-sys-onSurfaceMedium); - font-family: 'Google Sans Text', sans-serif !important; + font-family: 'Google Sans', sans-serif !important; opacity: 0.6; margin: 0; } diff --git a/src/app/app.ts b/src/app/app.ts index 6932da5..dc4e955 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -181,20 +181,33 @@ const customerServiceProjects: SuccessStory[] = [ } ]; -const accountingProjects: SuccessStory[] = [ +const dataPrivacyProjects: SuccessStory[] = [ { - title: 'Digitally Enabled Audit', + title: 'LLM-Powered Document Anonymisation', description: [ - 'Designed and developed tools and components for ETL, integration and processing to be used for auditing businesses', - 'Established best-practice coding standards within the software development team', - 'Significantly improved code quality and maintainability of the existing codebase', - 'Introduced static typing, static code analysis and functional-style programming to the Python code', - 'The developed component for extracting data from SAP is now being used for auditing businesses worldwide', + 'Built a system to automatically redact sensitive personal information from documents', + 'System uses LLMs and Natural Language Processing to identify sensitive personal information', + 'The LLMs used are hosted in a GDPR-compliant manner', + 'Resulting system allows for the upload of PDF files, often containing hundreds of pages, and reliably returns a fully redacted version', + 'Even works for handwritten comments' + ], + image: 'redactions.png', + tech: [ + 'Python', 'LLM', 'OCR', 'langchain', 'RabbitMQ', + 'Kubernetes', 'Helm' ], - image: 'audit.png', - tech: ['Python', 'SAP S4/HANA', 'ABAP', 'Docker'], }, - + { + title: 'Synthetic Document Generation', + description: [ + 'Generated realistic synthetic documents for training AI systems using LLMs', + 'Addressed the scarcity of real documents containing highly sensitive and private information', + 'Produced training data that preserves the structural and semantic properties of real documents without exposing any actual personal data', + 'Avoids running afoul of data protection laws while still enabling effective AI model training' + ], + image: 'document_generation.png', + tech: ['Python', 'LLM', 'langchain', 'Docker'], + }, ]; const otherProjects: SuccessStory[] = [ @@ -210,19 +223,16 @@ const otherProjects: SuccessStory[] = [ tech: ['Python', 'Machine Learning', 'PostgreSQL'], }, { - title: 'LLM-Powered Document Anonymisation', + title: 'Digitally Enabled Audit', description: [ - 'Built a system to automatically redact sensitive personal information from documents', - 'System uses LLMs and Natural Language Processing to identify sensitive personal information', - 'The LLMs used are hosted in a GDPR-compliant manner', - 'Resulting system allows for the upload of PDF files, often containing hundreds of pages, and reliably returns a fully redacted version', - 'Even works for handwritten comments' - ], - image: 'redactions.png', - tech: [ - 'Python', 'LLM', 'OCR', 'langchain', 'RabbitMQ', - 'Kubernetes', 'Helm' + 'Designed and developed tools and components for ETL, integration and processing to be used for auditing businesses', + 'Established best-practice coding standards within the software development team', + 'Significantly improved code quality and maintainability of the existing codebase', + 'Introduced static typing, static code analysis and functional-style programming to the Python code', + 'The developed component for extracting data from SAP is now being used for auditing businesses worldwide', ], + image: 'audit.png', + tech: ['Python', 'SAP S4/HANA', 'ABAP', 'Docker'], }, ]; @@ -232,8 +242,8 @@ const repos: Repo[] = [ description: 'reflect-cpp is a C++-20/C++-26 library for fast serialisation, deserialisation and validation using reflection, similar to pydantic in Python, serde in Rust, encoding in Go or aeson in Haskell.', tech: ['C++', 'JSON', 'msgpack', 'parquet', 'XML', 'Avro'], - link: 'https://github.com/getml/reflect-cpp', - docs: 'https://rfl.getml.com/', + link: 'https://github.com/munich-data-engineering/reflect-cpp', + docs: 'https://munich-data-engineering.github.io/reflect-cpp', status: 'Stable', }, { @@ -241,8 +251,8 @@ const repos: Repo[] = [ description: 'sqlgen is a reflection-based ORM and SQL query generator for C++-20, similar to Python\'s SQLAlchemy/SQLModel or Rust\'s Diesel.', tech: ['C++', 'PostgreSQL', 'MySQL', 'sqlite', 'DuckDB'], - link: 'https://github.com/getml/sqlgen', - docs: 'https://getml.github.io/sqlgen/', + link: 'https://github.com/munich-data-engineering/sqlgen', + docs: 'https://munich-data-engineering.github.io/sqlgen/', status: 'Stable', }, ]; @@ -265,7 +275,7 @@ export class App { readonly tabNames = [ 'Energy', 'Healthcare', 'Automotive', 'Retail', - 'Customer Service', 'Accounting', 'Other' + 'Customer Service', 'Data Privacy', 'Other' ]; getSuccessStories(tabName: string): SuccessStory[] { @@ -284,8 +294,8 @@ export class App { } else if (tabName === 'Customer Service') { return customerServiceProjects; - } else if (tabName === 'Accounting') { - return accountingProjects; + } else if (tabName === 'Data Privacy') { + return dataPrivacyProjects; } else if (tabName === 'Other') { return otherProjects; diff --git a/src/index.html b/src/index.html index 4612350..177e6ad 100644 --- a/src/index.html +++ b/src/index.html @@ -9,12 +9,9 @@ - - - + + +