Add new templates and tests for improved functionality
- Created index.html template for the homepage with service cards and partner logos. - Added page_from_md.html template for rendering pages from markdown. - Developed services.html template detailing various services offered. - Implemented tests for link handling in markdown, ensuring external links open in new tabs and internal links function correctly. - Enhanced markdown parser tests to validate heading extraction, content rendering, and link safety. - Introduced utility tests for template rendering, HTML minification, and JavaScript minification. Co-authored-by: Copilot <copilot@github.com>
@@ -3,6 +3,7 @@
|
||||
|
||||
# vscode settings
|
||||
.vscode/
|
||||
v5.code-workspace
|
||||
|
||||
# python virtual environment
|
||||
.venv/
|
||||
@@ -10,3 +11,8 @@
|
||||
# python cache
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
#pytest cache
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.coverage
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# Nutzungsbedingungen – AllYouCanGET
|
||||
|
||||
## Impressum
|
||||
|
||||
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3 des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG)
|
||||
|
||||
```text
|
||||
All You Can GET
|
||||
c/o Sinn Consulting
|
||||
Im Dornäcker 16
|
||||
CH-8967 Widen
|
||||
georg AT allucanget DOT biz
|
||||
```
|
||||
|
||||
_Aktualisiert am: 22.10.2025_
|
||||
|
||||
Willkommen auf der Website von **AllYouCanGET – Sinn Consulting**, mit Sitz in Widen, Schweiz.
|
||||
Durch den Zugriff auf diese Website erklärst du dich mit den folgenden Nutzungsbedingungen einverstanden.
|
||||
Wenn du mit diesen Bedingungen nicht einverstanden bist, wird gebeten, die Website nicht zu nutzen.
|
||||
|
||||
---
|
||||
|
||||
## 1. Geltungsbereich
|
||||
|
||||
Diese Nutzungsbedingungen regeln den Zugriff auf und die Nutzung der von **AllYouCanGET – Sinn Consulting** (nachfolgend „AllYouCanGET“ oder „das Unternehmen“) betriebenen Website.
|
||||
Sie gelten für alle Besucherinnen und Besucher, Nutzerinnen und Nutzer dieser Website.
|
||||
|
||||
Für die Inanspruchnahme von Dienstleistungen des Unternehmens gelten die separaten **Allgemeinen Geschäftsbedingungen (AGB)**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Zweck der Website
|
||||
|
||||
Die Website dient der Information über die Dienstleistungen, Philosophie und Angebote von AllYouCanGET in den Bereichen
|
||||
**Business Consulting, Creative Development, Digital Marketing, Coaching und Technische Services**.
|
||||
|
||||
AllYouCanGET behält sich das Recht vor, Inhalte der Website jederzeit ohne Vorankündigung zu ändern, zu ergänzen oder zu entfernen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Urheberrecht und geistiges Eigentum
|
||||
|
||||
Alle Inhalte dieser Website – insbesondere Texte, Grafiken, Logos, Bilder, Design-Elemente und herunterladbare Materialien – sind urheberrechtlich und durch andere Schutzrechte geschützt.
|
||||
Sofern nicht anders angegeben, liegen alle Rechte bei **AllYouCanGET – Sinn Consulting**.
|
||||
|
||||
Das Anzeigen, Herunterladen oder Ausdrucken von Inhalten ist nur für den **privaten, nicht kommerziellen Gebrauch** erlaubt, sofern alle Urheberrechts- und Eigentumshinweise bestehen bleiben.
|
||||
Eine Vervielfältigung, Verbreitung, Bearbeitung oder Veröffentlichung von Inhalten zu kommerziellen Zwecken ist ohne ausdrückliche schriftliche Zustimmung von AllYouCanGET untersagt.
|
||||
|
||||
---
|
||||
|
||||
## 4. Nutzung der Website
|
||||
|
||||
Die Website darf nur zu rechtmässigen Zwecken und in einer Weise genutzt werden, die den Betrieb oder die Sicherheit der Website nicht beeinträchtigt.
|
||||
|
||||
Automatisierte Zugriffe (z. B. durch Bots oder Crawler) sind nur im Rahmen der in der Datei `robots.txt` festgelegten Regeln erlaubt.
|
||||
AllYouCanGET behält sich das Recht vor, den Zugriff auf die Website jederzeit einzuschränken oder zu sperren.
|
||||
|
||||
---
|
||||
|
||||
## 5. Externe Links und Inhalte Dritter
|
||||
|
||||
Diese Website kann Links zu externen Websites Dritter enthalten.
|
||||
AllYouCanGET hat keinen Einfluss auf deren Inhalte und übernimmt keinerlei Verantwortung oder Haftung für deren Richtigkeit, Rechtmässigkeit oder Verfügbarkeit.
|
||||
Der Zugriff auf solche externen Seiten erfolgt auf eigenes Risiko der Nutzerin oder des Nutzers.
|
||||
|
||||
---
|
||||
|
||||
## 6. Vertraulichkeit und Datenschutz
|
||||
|
||||
AllYouCanGET behandelt personenbezogene Daten, die über diese Website übermittelt werden (z. B. über Kontaktformulare oder Newsletter-Anmeldungen), **vertraulich** und gemäss den geltenden Schweizer Datenschutzbestimmungen.
|
||||
Die Daten werden ausschliesslich für den angegebenen Zweck verwendet.
|
||||
Weitere Informationen finden sich in der separaten **Datenschutzerklärung**.
|
||||
|
||||
Nicht personenbezogene Informationen oder Materialien, die über die Website übermittelt werden (z. B. Feedback, Ideen, Konzepte), gelten als **nicht vertraulich**.
|
||||
AllYouCanGET darf solche Informationen frei verwenden, sofern nichts anderes schriftlich vereinbart wurde.
|
||||
|
||||
---
|
||||
|
||||
## 7. Haftungsausschluss
|
||||
|
||||
AllYouCanGET ist bemüht, die Inhalte dieser Website sorgfältig und aktuell zu halten.
|
||||
Dennoch wird keine Gewähr für die Richtigkeit, Vollständigkeit oder Verfügbarkeit der bereitgestellten Informationen übernommen.
|
||||
|
||||
AllYouCanGET haftet ausschliesslich für Schäden, die durch **vorsätzliches oder grobfahrlässiges Verhalten** verursacht werden.
|
||||
Eine Haftung für **indirekte oder Folgeschäden**, insbesondere Datenverluste oder entgangenen Gewinn, ist ausgeschlossen.
|
||||
|
||||
---
|
||||
|
||||
## 8. Änderungen der Website und Nutzungsbedingungen
|
||||
|
||||
AllYouCanGET kann die Inhalte der Website sowie diese Nutzungsbedingungen jederzeit und ohne Vorankündigung ändern oder aktualisieren.
|
||||
Es gilt stets die zum Zeitpunkt des Zugriffs auf der Website veröffentlichte Fassung.
|
||||
|
||||
---
|
||||
|
||||
## 9. Anwendbares Recht und Gerichtsstand
|
||||
|
||||
Diese Nutzungsbedingungen unterstehen ausschliesslich dem **schweizerischen Recht**.
|
||||
Gerichtsstand für alle Streitigkeiten im Zusammenhang mit der Nutzung dieser Website ist **Widen, Schweiz**.
|
||||
|
||||
---
|
||||
|
||||
**AllYouCanGET – Sinn Consulting**
|
||||
Widen, Schweiz
|
||||
[https://www.allyoucanget.ch](https://www.allyoucanget.biz)
|
||||
@@ -0,0 +1,89 @@
|
||||
# **Allgemeine Geschäftsbedingungen (AGB)**
|
||||
|
||||
**AllYouCanGET – Sinn Consulting**
|
||||
Widen, Schweiz
|
||||
|
||||
---
|
||||
|
||||
## **1. Geltungsbereich**
|
||||
|
||||
Diese Allgemeinen Geschäftsbedingungen (AGB) gelten für sämtliche Dienstleistungen der **AllYouCanGET – Sinn Consulting** (nachfolgend „das Unternehmen“).
|
||||
Sie finden Anwendung auf Verträge mit **Privatpersonen (B2C)** sowie **Unternehmen (B2B)**. Mit der Beauftragung des Unternehmens anerkennt der Kunde diese AGB in vollem Umfang.
|
||||
|
||||
---
|
||||
|
||||
## **2. Leistungen**
|
||||
|
||||
Das Unternehmen erbringt Dienstleistungen in den Bereichen **Business Consulting, Creative Development, Digital Marketing, Coaching und Technische Services**.
|
||||
Art, Umfang und Ziel der jeweiligen Dienstleistung werden individuell schriftlich oder elektronisch vereinbart.
|
||||
|
||||
---
|
||||
|
||||
## **3. Angebote und Vertragsabschluss**
|
||||
|
||||
Alle Angebote des Unternehmens sind **unverbindlich**, bis sie schriftlich bestätigt werden.
|
||||
Änderungen, Ergänzungen oder Zusatzleistungen bedürfen ebenfalls der **schriftlichen Bestätigung** durch das Unternehmen.
|
||||
|
||||
---
|
||||
|
||||
## **4. Preise und Zahlungsbedingungen**
|
||||
|
||||
Sofern nicht anders vereinbart, verstehen sich alle Preise in **Schweizer Franken (CHF)**, exklusive Mehrwertsteuer (sofern anwendbar).
|
||||
Die Rechnungsstellung erfolgt **nach Abschluss der Dienstleistung**.
|
||||
Rechnungen sind innerhalb von **30 Tagen** ab Rechnungsdatum ohne Abzug zu bezahlen.
|
||||
Bei Zahlungsverzug behält sich das Unternehmen das Recht vor, **Mahngebühren** und **Verzugszinsen** zu erheben.
|
||||
|
||||
---
|
||||
|
||||
## **5. Annullierung und Rückerstattung**
|
||||
|
||||
Annullierungen durch den Kunden müssen **schriftlich** erfolgen.
|
||||
|
||||
- **Bis 7 Tage vor Leistungserbringung:** Rückerstattung von 50 % des vereinbarten Honorars.
|
||||
- **Weniger als 7 Tage vor Leistungserbringung:** keine Rückerstattung möglich.
|
||||
|
||||
Das Unternehmen behält sich vor, Dienstleistungen aus wichtigen Gründen (z. B. Krankheit, unvorhergesehene Ereignisse) zu verschieben oder abzusagen. In diesem Fall wird ein neuer Termin vereinbart oder bereits geleistete Zahlungen werden zurückerstattet.
|
||||
|
||||
---
|
||||
|
||||
## **6. Haftung**
|
||||
|
||||
Das Unternehmen haftet ausschliesslich für **vorsätzliches oder grobfahrlässiges Verhalten**.
|
||||
Eine Haftung für leichte Fahrlässigkeit, **indirekte Schäden**, **Folgeschäden**, **entgangenen Gewinn** oder **Datenverlust** ist ausdrücklich ausgeschlossen.
|
||||
Der Kunde bleibt für die Umsetzung und die Entscheidungen, die aus der Beratung resultieren, selbst verantwortlich.
|
||||
|
||||
---
|
||||
|
||||
## **7. Urheberrecht und Nutzungsrechte**
|
||||
|
||||
Alle vom Unternehmen erstellten Unterlagen, Konzepte, Designs und Materialien bleiben bis zur **vollständigen Bezahlung** Eigentum des Unternehmens.
|
||||
Sofern nicht anders vereinbart, verbleiben sämtliche **Urheber- und Nutzungsrechte** beim Unternehmen.
|
||||
Eine Weitergabe, Vervielfältigung oder Nutzung der Materialien zu anderen Zwecken ist ohne vorherige schriftliche Zustimmung nicht gestattet.
|
||||
|
||||
---
|
||||
|
||||
## **8. Vertraulichkeit**
|
||||
|
||||
Das Unternehmen verpflichtet sich, alle im Rahmen der Zusammenarbeit erhaltenen Informationen und Daten des Kunden **vertraulich** zu behandeln.
|
||||
Diese Pflicht besteht auch nach Beendigung der Geschäftsbeziehung fort.
|
||||
Der Kunde verpflichtet sich ebenso, vertrauliche Informationen über das Unternehmen nicht an Dritte weiterzugeben.
|
||||
|
||||
---
|
||||
|
||||
## **9. Datenschutz**
|
||||
|
||||
Personenbezogene Daten werden ausschliesslich zur **Erbringung und Verwaltung der Dienstleistungen** verwendet.
|
||||
Eine Weitergabe an Dritte erfolgt nur mit ausdrücklicher Zustimmung des Kunden oder wenn eine gesetzliche Verpflichtung besteht.
|
||||
|
||||
---
|
||||
|
||||
## **10. Anwendbares Recht und Gerichtsstand**
|
||||
|
||||
Diese AGB sowie alle Vertragsbeziehungen zwischen dem Unternehmen und dem Kunden unterstehen ausschliesslich dem **schweizerischen Recht**.
|
||||
Gerichtsstand ist **Widen, Schweiz**.
|
||||
|
||||
---
|
||||
|
||||
**AllYouCanGET – Sinn Consulting**
|
||||
Widen, Schweiz
|
||||
_(Gültig ab 01.01.2025)_
|
||||
@@ -0,0 +1,234 @@
|
||||
# Our Coaching Areas
|
||||
|
||||
Comprehensive coaching programs tailored to your professional and personal growth
|
||||
|
||||
##  Career Advice
|
||||
|
||||
Navigate your career path with expert guidance tailored to your industry and location.
|
||||
|
||||
### IT Career
|
||||
|
||||
- Career paths in software development
|
||||
- Technical vs management track
|
||||
- Transitioning between specialties
|
||||
|
||||
### Switzerland Specifics
|
||||
|
||||
- Work culture and expectations
|
||||
- Salary negotiations
|
||||
- Work permits and regulations
|
||||
|
||||
### Germany Specifics
|
||||
|
||||
- Job market trends
|
||||
- Industry hubs and opportunities
|
||||
|
||||
### Remote Work
|
||||
|
||||
- Building a remote work routine
|
||||
- Communication strategies
|
||||
|
||||
### Freelancing
|
||||
|
||||
- Setting up as independent contractor
|
||||
- Client acquisition and retention
|
||||
- Pricing strategies and negotiation
|
||||
|
||||
### Startups
|
||||
|
||||
- Evaluating startup opportunities
|
||||
- Equity considerations
|
||||
- Growth expectations
|
||||
|
||||
### Corporates
|
||||
|
||||
- Navigating corporate structures
|
||||
- Internal mobility
|
||||
- Building influence
|
||||
|
||||
### Consulting
|
||||
|
||||
- Types of consulting roles
|
||||
- Client management
|
||||
- Balancing multiple projects
|
||||
|
||||
##  Personal Development
|
||||
|
||||
Discover your values, strengths, and purpose to create a fulfilling life and career.
|
||||
|
||||
### Values
|
||||
|
||||
- Value identification exercises
|
||||
- Aligning career with personal values
|
||||
- Identity Workshop
|
||||
|
||||
### Ikigai
|
||||
|
||||
- Finding purpose through passion
|
||||
- Mission, vocation, and profession
|
||||
- Practical discovery exercises
|
||||
|
||||
### Strengths
|
||||
|
||||
- Assessment tools and frameworks
|
||||
- Leveraging strengths professionally
|
||||
|
||||
### Weaknesses
|
||||
|
||||
- Growth mindset approaches
|
||||
- Strategic improvement planning
|
||||
|
||||
### Vision
|
||||
|
||||
- Creating personal vision statements
|
||||
- Long-term life planning
|
||||
- Visualization techniques
|
||||
|
||||
### Goals
|
||||
|
||||
- SMART goal framework
|
||||
- Balancing short and long-term objectives
|
||||
|
||||
### Agile Self Organization
|
||||
|
||||
- Personal Kanban implementation
|
||||
- Quarterly planning and review cycles
|
||||
- Agile methods for personal productivity
|
||||
|
||||
##  Leadership Coaching
|
||||
|
||||
Develop essential leadership skills to inspire teams and drive organizational success.
|
||||
|
||||
### Leadership Styles
|
||||
|
||||
- Management vs Leadership
|
||||
- Situational leadership approaches
|
||||
- Transformational vs transactional
|
||||
|
||||
### Communication
|
||||
|
||||
- Active listening techniques
|
||||
- Delivering difficult messages
|
||||
- Cross-cultural communication
|
||||
|
||||
### Feedback
|
||||
|
||||
- Structured feedback frameworks
|
||||
- Creating feedback culture
|
||||
- Growth-oriented approaches
|
||||
|
||||
### Delegation
|
||||
|
||||
- RACI and DACI models
|
||||
- Identifying tasks to delegate
|
||||
- Building team capacity
|
||||
|
||||
### Decision Making
|
||||
|
||||
- OODA loop, DECIDE model
|
||||
- Data-driven decisions
|
||||
- Managing decision paralysis
|
||||
|
||||
### Conflict Management
|
||||
|
||||
- Conflict resolution models
|
||||
- Mediation techniques
|
||||
- Transforming conflict to opportunity
|
||||
|
||||
### Motivation
|
||||
|
||||
- Intrinsic vs extrinsic motivation
|
||||
- SCARF and Drive frameworks
|
||||
- Tailoring to individual needs
|
||||
|
||||
### Empathy & Compassion
|
||||
|
||||
- Building empathetic leadership
|
||||
- Compassion without compromising
|
||||
|
||||
### Trust
|
||||
|
||||
- Trust-building exercises
|
||||
- Trust in remote teams
|
||||
- Rebuilding broken trust
|
||||
|
||||
### Psychological Safety
|
||||
|
||||
- Assessment techniques
|
||||
- Creating safety in teams
|
||||
- Connection to innovation
|
||||
|
||||
### Team Building
|
||||
|
||||
- Tuckman's team formation
|
||||
- Remote team activities
|
||||
- Cross-functional dynamics
|
||||
|
||||
### Agile Project Management
|
||||
|
||||
- Project roles and responsibilities
|
||||
- Agile hierarchies
|
||||
- Balancing agility with governance
|
||||
|
||||
##  Technical Coaching
|
||||
|
||||
Master technical skills and best practices in software development and IT infrastructure.
|
||||
|
||||
### Software and Web Development
|
||||
|
||||
#### Scalability
|
||||
|
||||
- Horizontal vs vertical scaling
|
||||
- Distributed systems principles
|
||||
- Load balancing strategies
|
||||
|
||||
#### Browser
|
||||
|
||||
- Developer tools mastery
|
||||
- Performance optimization
|
||||
- Extension development
|
||||
|
||||
### Operating Systems
|
||||
|
||||
#### Linux
|
||||
|
||||
- Debian, Ubuntu
|
||||
- RedHat, Fedora, CentOS
|
||||
- Arch, Manjaro
|
||||
- SUSE, openSUSE
|
||||
|
||||
#### Windows
|
||||
|
||||
- Windows 10 & 11
|
||||
- Windows Server 2019
|
||||
- Windows Server 2022
|
||||
|
||||
#### macOS
|
||||
|
||||
- macOS basics
|
||||
- System administration
|
||||
- Shell commands
|
||||
|
||||
### Development Tools
|
||||
|
||||
#### Git
|
||||
|
||||
- Advanced git workflows
|
||||
- Git hooks and automation
|
||||
- Collaboration strategies
|
||||
|
||||
#### Docker
|
||||
|
||||
- Container optimization
|
||||
- Docker Compose
|
||||
- Kubernetes orchestration
|
||||
|
||||
#### Visual Studio Code
|
||||
|
||||
- Extension ecosystem
|
||||
- Customization and settings
|
||||
- Productivity optimization
|
||||
|
||||
## Ready to Accelerate Your Growth?
|
||||
|
||||
Let's work together to unlock your full potential
|
||||
@@ -0,0 +1,81 @@
|
||||
# Terms of Use – AllYouCanGET
|
||||
|
||||
##  Impressum
|
||||
|
||||
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3 des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG):
|
||||
|
||||
All You Can GET, c/o Sinn Consulting, Im Dornäcker 16, CH-8967 Widen - georg AT allucanget DOT biz
|
||||
|
||||
## Welcome
|
||||
|
||||
Welcome to the website of **AllYouCanGET – Sinn Consulting**, based in Widen, Switzerland.
|
||||
By accessing or using this website, you agree to be bound by the following Terms of Use.
|
||||
If you do not agree, please refrain from using this site.
|
||||
|
||||
## 1. Scope of Application
|
||||
|
||||
These Terms of Use govern the access to and use of the website operated by **AllYouCanGET – Sinn Consulting** (hereinafter “AllYouCanGET” or “the Company”).
|
||||
They apply to all visitors, users, and other persons who access the website.
|
||||
|
||||
Separate agreements apply to consulting and service contracts concluded with clients. For such services, the **General Terms and Conditions (GTC)** of AllYouCanGET apply.
|
||||
|
||||
## 2. Purpose of the Website
|
||||
|
||||
This website serves to provide information about the Company’s services, philosophy, and current offerings in the areas of **business consulting, creative development, digital marketing, coaching, and technical services**.
|
||||
|
||||
AllYouCanGET reserves the right to update, modify, or remove website content at any time without prior notice.
|
||||
|
||||
## 3. Intellectual Property and Copyright
|
||||
|
||||
All content on this website — including text, graphics, logos, images, design elements, and downloadable materials — is protected by copyright and other intellectual property rights.
|
||||
Unless otherwise stated, all rights belong to **AllYouCanGET – Sinn Consulting**.
|
||||
|
||||
You may view, download, and print website content **for personal and non-commercial use only**, provided that all copyright and proprietary notices remain intact.
|
||||
Any reproduction, distribution, modification, or publication of website content for commercial purposes is prohibited without prior written permission from AllYouCanGET.
|
||||
|
||||
## 4. Use of the Website
|
||||
|
||||
Users agree to use this website responsibly and only for lawful purposes.
|
||||
Any use that could impair or disrupt the functionality of the website or violate applicable laws is prohibited.
|
||||
|
||||
Automated access (e.g., by bots or crawlers) is only permitted within the limits defined by the site’s `robots.txt` file.
|
||||
AllYouCanGET reserves the right to restrict or block access to the website at its sole discretion.
|
||||
|
||||
## 5. External Links and Third-Party Content
|
||||
|
||||
This website may contain links to external websites operated by third parties.
|
||||
AllYouCanGET has no control over the content of these websites and assumes no responsibility or liability for their accuracy, legality, or reliability.
|
||||
Access to linked websites is at the user’s own risk.
|
||||
|
||||
## 6. Confidentiality and Data Protection
|
||||
|
||||
AllYouCanGET treats personal data provided via this website (e.g., through contact forms or newsletter subscriptions) as **strictly confidential**.
|
||||
Data is processed solely for the stated purpose and in accordance with applicable Swiss data protection regulations.
|
||||
Please refer to our **Privacy Policy** for detailed information on how personal data is handled.
|
||||
|
||||
Any non-personal information or material sent to AllYouCanGET via the website (e.g., feedback, ideas, or concepts) is deemed non-confidential, and AllYouCanGET may use such information freely, unless otherwise agreed in writing.
|
||||
|
||||
## 7. Disclaimer
|
||||
|
||||
AllYouCanGET strives to ensure that the information on this website is accurate and up to date.
|
||||
However, no guarantee is given for the completeness, correctness, or availability of the information provided.
|
||||
|
||||
AllYouCanGET assumes no liability for any damages arising from the use of or inability to use the website or its contents, unless caused by gross negligence or intent.
|
||||
Liability for indirect or consequential damages, including data loss or lost profits, is excluded.
|
||||
|
||||
## 8. Changes to the Website and Terms
|
||||
|
||||
AllYouCanGET may change, suspend, or discontinue any part of this website, or update these Terms of Use at any time without prior notice.
|
||||
The current version published on the website applies.
|
||||
|
||||
## 9. Applicable Law and Jurisdiction
|
||||
|
||||
These Terms of Use are governed exclusively by **Swiss law**.
|
||||
|
||||
The exclusive place of jurisdiction is **Widen, Switzerland**.
|
||||
|
||||
---
|
||||
|
||||
## Last Update
|
||||
|
||||
Effective from 01.01.2025
|
||||
@@ -0,0 +1,122 @@
|
||||
# Streamline operations, optimize performance, and drive innovation with AllYouCanGET
|
||||
|
||||
Streamline operations, optimize performance, and drive innovation with AllYouCanGET
|
||||
|
||||
##  IT Consulting
|
||||
|
||||
Strategic technology solutions to drive your digital transformation
|
||||
|
||||
### ✓ IT Strategy & Planning
|
||||
|
||||
A strategic view on business goals helps to align technology roadmaps accordingly
|
||||
|
||||
We develop comprehensive IT strategies that align with your business goals and drive digital transformation
|
||||
|
||||
### ✓ Technology Assessment
|
||||
|
||||
We evaluate existing IT infrastructure and identify improvement areas
|
||||
|
||||
A thorough assessment of your current technology landscape to identify strengths, weaknesses, and opportunities for improvement
|
||||
|
||||
### ✓ Enterprise Architecture
|
||||
|
||||
We design and implement scalable IT architectures that align with business objectives
|
||||
|
||||
Our enterprise architecture services help you design and implement scalable IT architectures that align with your business objectives
|
||||
|
||||
### ✓ Cybersecurity
|
||||
|
||||
Protect your digital assets! We guide you through comprehensive security strategies
|
||||
|
||||
Our cybersecurity services help you protect your digital assets and ensure compliance with industry standards
|
||||
|
||||
##  Management Consulting
|
||||
|
||||
Optimize operations and accelerate business growth
|
||||
|
||||
### ✓ Strategy Development
|
||||
|
||||
We develop comprehensive strategies to drive business success
|
||||
|
||||
Tailored strategies that align with your business goals and drive growth
|
||||
|
||||
### ✓ Process Optimization
|
||||
|
||||
We improve efficiency by streamlining operations and reducing costs
|
||||
|
||||
Our process optimization services help you identify bottlenecks, eliminate waste, and enhance productivity
|
||||
|
||||
### ✓ Change Management
|
||||
|
||||
We implement effective change management strategies to ensure smooth transitions
|
||||
|
||||
Our change management services help you navigate organizational change and ensure successful adoption of new initiatives
|
||||
|
||||
### ✓ Financial Analysis
|
||||
|
||||
We provide data-driven insights for informed financial decision-making
|
||||
|
||||
Our financial analysis services help you make informed decisions based on data-driven insights
|
||||
|
||||
##  Infrastructure Services
|
||||
|
||||
Build robust foundations for your business success
|
||||
|
||||
### ✓ Cloud Solutions
|
||||
|
||||
Build scalable and flexible cloud infrastructures tailored to your needs
|
||||
|
||||
We design and implement scalable and flexible cloud infrastructures that meet your business needs
|
||||
|
||||
### ✓ Network Design
|
||||
|
||||
We design and implement robust network architectures to ensure seamless connectivity
|
||||
|
||||
Our network design services help you create robust network architectures that ensure seamless connectivity and optimal performance
|
||||
|
||||
### ✓ System Integration
|
||||
|
||||
We integrate diverse systems and applications to streamline processes and enhance data flow
|
||||
|
||||
Our system integration services help you connect disparate systems and applications to streamline processes and enhance data flow
|
||||
|
||||
### ✓ Security Implementation
|
||||
|
||||
We implement comprehensive security measures to protect your infrastructure
|
||||
|
||||
Our security implementation services help you safeguard your infrastructure against cyber threats and ensure compliance with industry standards
|
||||
|
||||
## Our Partners
|
||||
|
||||
We collaborate with leading technology providers to deliver the best solutions for your business.
|
||||
|
||||
###
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Projects
|
||||
|
||||
### Open Mic Odyssey
|
||||
|
||||
Website for a documentary film project about three best friends embarking on an outrageous adventure.
|
||||
|
||||
[Open Mic Odyssey](https://openmicodyssey.com)
|
||||
|
||||
### Bobby Ludlam
|
||||
|
||||
A landing page for a stand-up comedian, artist and entrepeneur.
|
||||
|
||||
[Bobby Ludlam](https://bobbyludlam.com)
|
||||
|
||||
### William Montgomery
|
||||
|
||||
Wordpress-based website for a stand-up comedian.
|
||||
|
||||
[William Montgomery](https://williamfmontgomery.com)
|
||||
@@ -0,0 +1,55 @@
|
||||
# Our Services
|
||||
|
||||
Comprehensive solutions to transform your business
|
||||
|
||||
##  IT Consulting
|
||||
|
||||
Comprehensive IT solutions to drive digital transformation and optimize your technology infrastructure.
|
||||
|
||||
###  IT Strategy & Planning
|
||||
|
||||
Develop technology roadmaps aligned with business objectives
|
||||
|
||||
###  Infrastructure Management
|
||||
|
||||
Design and implement robust IT infrastructure solutions
|
||||
|
||||
###  Cybersecurity
|
||||
|
||||
Protect your assets with advanced security measures
|
||||
|
||||
##  Management Consulting
|
||||
|
||||
Strategic business solutions to improve efficiency and drive growth.
|
||||
|
||||
###  Process Optimization
|
||||
|
||||
Streamline operations and improve business efficiency
|
||||
|
||||
###  Change Management
|
||||
|
||||
Guide organizational transformation effectively
|
||||
|
||||
###  Financial Analysis
|
||||
|
||||
Data-driven financial planning and optimization
|
||||
|
||||
##  Infrastructure Services
|
||||
|
||||
Build robust foundations for your business success
|
||||
|
||||
###  Cloud Solutions
|
||||
|
||||
Leverage cloud technology for scalable solutions
|
||||
|
||||
###  Network Design
|
||||
|
||||
Create secure and efficient network architectures
|
||||
|
||||
###  System Integration
|
||||
|
||||
Seamlessly integrate systems for optimal performance
|
||||
|
||||
## Need Customized Solutions?
|
||||
|
||||
Let's discuss how we can help transform your business
|
||||
@@ -0,0 +1,56 @@
|
||||
# General Terms and Conditions (GTC)
|
||||
|
||||
## 1. Scope of Application
|
||||
|
||||
These General Terms and Conditions (GTC) apply to all services provided by **AllYouCanGET – Sinn Consulting** (hereinafter “the Company”) to its clients, whether private individuals or businesses. By commissioning the Company, the client accepts these GTC in full.
|
||||
|
||||
## 2. Services
|
||||
|
||||
The Company provides services in the areas of **business consulting, creative development, digital marketing, coaching, and technical services**. The specific scope, content, and objectives of a service are agreed upon individually in writing or electronically.
|
||||
|
||||
## 3. Offers and Agreements
|
||||
|
||||
All offers are non-binding until confirmed by the Company in writing. Agreements, changes, or additional services are valid only with written confirmation.
|
||||
|
||||
## 4. Prices and Payment Terms
|
||||
|
||||
Unless otherwise agreed, prices are stated in Swiss francs (CHF) and exclude VAT (if applicable).
|
||||
Invoices are issued after completion of the agreed service and are payable within **30 days** from the invoice date without deductions.
|
||||
In case of late payment, the Company reserves the right to charge reminder fees and default interest.
|
||||
|
||||
## 5. Cancellations and Refunds
|
||||
|
||||
Cancellations by the client must be made in writing.
|
||||
|
||||
- **Up to 7 days before the service date:** partial refund (50%) of the agreed amount.
|
||||
- **Less than 7 days before the service date:** no refund possible.
|
||||
The Company reserves the right to cancel or postpone services for important reasons (e.g. illness, unforeseen events), in which case a new date will be arranged or any payments already made will be refunded.
|
||||
|
||||
## 6. Liability
|
||||
|
||||
The Company is liable only for **intentional or grossly negligent actions**. Liability for slight negligence, indirect or consequential damages, lost profits, or data loss is excluded.
|
||||
The client remains responsible for the decisions and results derived from the consulting services.
|
||||
|
||||
## 7. Intellectual Property
|
||||
|
||||
All materials, concepts, designs, and documentation created by the Company remain the property of the Company until full payment has been received.
|
||||
Unless otherwise agreed, the Company retains all copyrights and usage rights to its materials, which may not be copied, shared, or used for other purposes without prior written consent.
|
||||
|
||||
## 8. Confidentiality
|
||||
|
||||
The Company treats all information and data provided by clients as **strictly confidential**. This obligation continues after the business relationship ends. The client likewise undertakes to maintain confidentiality regarding all information obtained about the Company.
|
||||
|
||||
## 9. Data Protection
|
||||
|
||||
Personal data is collected and processed solely for the purpose of providing and managing services. Data is not shared with third parties without consent, except where legally required.
|
||||
|
||||
## 10. Applicable Law and Jurisdiction
|
||||
|
||||
These GTC and all contractual relationships between the Company and the client are governed exclusively by **Swiss law**.
|
||||
The exclusive place of jurisdiction is **Widen, Switzerland**.
|
||||
|
||||
---
|
||||
|
||||
## Last Update
|
||||
|
||||
Effective from 01.01.2025
|
||||
@@ -0,0 +1,94 @@
|
||||
# Web Services – AllYouCanGET
|
||||
|
||||
Reliable, secure, and fully managed hosting solutions tailored for your business
|
||||
|
||||
##  Managed Hosting Solutions
|
||||
|
||||
Enjoy peace of mind with our fully managed hosting services. We handle maintenance, updates, backups, and security — so you can focus on your business.
|
||||
|
||||
### Managed CMS Hosting (PHP-based)
|
||||
|
||||
Ideal for WordPress and similar CMS platforms.
|
||||
|
||||
- Daily backups
|
||||
- System and plugin updates
|
||||
- Security screening and monitoring
|
||||
- Starting from **25 CHF / month (incl. VAT)**
|
||||
|
||||
### Managed Application Hosting
|
||||
|
||||
(Node.js / Python)
|
||||
|
||||
Perfect for modern web applications and APIs.
|
||||
|
||||
- Daily backups
|
||||
- Framework and dependency updates
|
||||
- Security screening and optimization
|
||||
- Starting from **25 CHF / month (incl. VAT)**
|
||||
|
||||
### Managed Docker Hosting
|
||||
|
||||
Flexible and containerized environments for developers.
|
||||
|
||||
- Daily backups
|
||||
- Security screening and resource monitoring
|
||||
- Starting from **25 CHF / month (incl. VAT)**
|
||||
|
||||
##  Hosting Packages
|
||||
|
||||
Simple, transparent, and scalable hosting plans with Swiss reliability.
|
||||
|
||||
### Basic Hosting
|
||||
|
||||
- **2 GB Diskspace**
|
||||
- **1 Domain**
|
||||
- **Unlimited Emails**
|
||||
- **1 GB RAM**
|
||||
- **SSH Access**
|
||||
- **10 CHF / month (incl. VAT)**
|
||||
|
||||
### Standard Hosting
|
||||
|
||||
- **5 GB Diskspace**
|
||||
- **1 Domain**
|
||||
- **Unlimited Emails**
|
||||
- **2 GB RAM**
|
||||
- **SSH Access**
|
||||
- **25 CHF / month (incl. VAT)**
|
||||
|
||||
### Premium Hosting
|
||||
|
||||
- **10 GB Diskspace**
|
||||
- **1 Domain**
|
||||
- **Unlimited Emails**
|
||||
- **4 GB RAM**
|
||||
- **SSH Access**
|
||||
- **50 CHF / month (incl. VAT)**
|
||||
|
||||
##  Why Choose AllYouCanGET?
|
||||
|
||||
### Reliable Swiss Hosting
|
||||
|
||||
- Swiss data protection and hosting standards
|
||||
- 24/7 monitoring and proactive security
|
||||
- Daily backups included in all plans
|
||||
- Scalable resources for growing businesses
|
||||
- Expert technical support from experienced professionals
|
||||
|
||||
### Seamless Migration
|
||||
|
||||
- Free migration assistance for new customers
|
||||
- Minimal downtime during transition
|
||||
- Comprehensive support throughout the migration process
|
||||
|
||||
### Custom Solutions
|
||||
|
||||
- Tailored hosting environments to fit your needs
|
||||
- Flexible resource allocation and scaling options
|
||||
- Expert advice on architecture and optimization
|
||||
- Integration with third-party services and tools
|
||||
- Performance tuning for optimal speed and reliability
|
||||
|
||||
## Ready to Get Started?
|
||||
|
||||
Let’s set up your hosting today — secure, managed, and built for growth.
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"index.html": {
|
||||
"name": "Home",
|
||||
"url": "index.html",
|
||||
"active": "False",
|
||||
"page_title": "Transform Your Business",
|
||||
"page_subtitle": "with expert IT & Management Consulting",
|
||||
"page_cta": "See all Services",
|
||||
"page_cta_url": "services.html",
|
||||
"meta": {
|
||||
"title": "AllYouCanGET - IT & Management Consulting",
|
||||
"description": "AllYouCanGET is an expert IT & Management Consulting firm helping businesses transform their operations and drive growth through technology and strategy solutions.",
|
||||
"keywords": "IT consulting services, Management consulting solutions, Digital transformation, Strategic technology solutions, IT strategy and planning, Technology assessment, Enterprise architecture consulting, Cybersecurity services, Infrastructure services, Cloud solutions, Network design and implementation, System integration, Security implementation, Streamline operations, Optimize business performance, Process optimization, Change management, Strategy development, Financial analysis, Business growth acceleration, Operations consulting, Expert consulting team, Business innovation, AllYouCanGET consulting",
|
||||
"og_description": "Transform your business with expert IT and Management consulting. We streamline operations, optimize performance, and drive innovation."
|
||||
}
|
||||
},
|
||||
"services.html": {
|
||||
"name": "Services",
|
||||
"url": "services.html",
|
||||
"active": "False",
|
||||
"page_title": "AllYouCanGET Services",
|
||||
"page_subtitle": "IT & Management Consulting",
|
||||
"page_cta": "Get Started",
|
||||
"page_cta_url": "#contact-form",
|
||||
"meta": {
|
||||
"title": "Our Services - IT & Management Consulting | AllYouCanGET",
|
||||
"description": "AllYouCanGET offers IT consulting services and management consulting solutions to help businesses drive digital transformation and optimize operations. Our expert consulting team provides strategic technology solutions to streamline operations, optimize business performance, and accelerate business growth. Contact us for a free consultation.",
|
||||
"keywords": "IT consulting services, Management consulting solutions, Digital transformation, Strategic technology solutions, IT strategy and planning, Technology assessment, Enterprise architecture consulting, Cybersecurity services, Infrastructure services, Cloud solutions, Network design and implementation, System integration, Security implementation, Streamline operations, Optimize business performance, Process optimization, Change management, Strategy development, Financial analysis, Business growth acceleration, Operations consulting, Expert consulting team, Business innovation, AllYouCanGET consulting",
|
||||
"og_description": "Explore our expert IT, Management, and Infrastructure consulting services designed to drive growth and efficiency for your business."
|
||||
}
|
||||
},
|
||||
"webservices.html": {
|
||||
"name": "Web Services",
|
||||
"url": "webservices.html",
|
||||
"active": "False",
|
||||
"page_title": "Web Services Solutions",
|
||||
"page_subtitle": "Scalable and Secure Web Services",
|
||||
"page_cta": "Learn More",
|
||||
"page_cta_url": "#contact-form",
|
||||
"meta": {
|
||||
"title": "Web Services - Scalable and Secure Solutions | AllYouCanGET",
|
||||
"description": "AllYouCanGET provides scalable and secure web services solutions to help businesses enhance their online presence and improve customer engagement. Our expert team delivers customized web services tailored to your business needs. Contact us for more information.",
|
||||
"keywords": "Web services solutions, Scalable web services, Secure web services, Online presence enhancement, Customer engagement, Customized web services, Business web solutions, IT consulting, Management consulting, AllYouCanGET consulting",
|
||||
"og_description": "Discover our scalable and secure web services solutions designed to enhance your online presence and engage customers effectively."
|
||||
}
|
||||
},
|
||||
"coaching.html": {
|
||||
"name": "Coaching",
|
||||
"url": "coaching.html",
|
||||
"active": "False",
|
||||
"page_title": "Professional Coaching Services",
|
||||
"page_subtitle": "Unlock Your Potential Through Expert Mentoring",
|
||||
"page_cta": "Start Your Journey",
|
||||
"page_cta_url": "#contact-form",
|
||||
"meta": {
|
||||
"title": "Professional Coaching Services | AllYouCanGET",
|
||||
"description": "AllYouCanGET offers professional coaching services in Career Advice, Personal Development, Leadership, and Technical Skills—helping individuals unlock their potential and achieve their personal and professional goals through expert mentoring and guidance.",
|
||||
"keywords": "Coaching, Mentoring, Career Advice, Personal Development, Leadership Coaching, Technical Coaching, Software Development, IT Career, Switzerland, Germany, Remote Work, Freelancing, Startups, Corporates, Consulting, Agile, Leadership, Technical Skills, Professional coaching, Career coaching, Executive coaching, Team coaching, Business coaching",
|
||||
"og_description": "Transform your career with AllYouCanGET's professional coaching services. Contact us for a free consultation."
|
||||
}
|
||||
},
|
||||
"imprint.html": {
|
||||
"name": "Imprint",
|
||||
"url": "imprint.html",
|
||||
"active": "False",
|
||||
"page_title": "AllYouCanGET Imprint",
|
||||
"page_subtitle": "IT & Management Consulting",
|
||||
"page_cta": "Contact Us",
|
||||
"page_cta_url": "#contact-form",
|
||||
"meta": {
|
||||
"title": "Imprint | AllYouCanGET",
|
||||
"description": "Legal imprint and contact information for AllYouCanGET - Sinn Consulting. Find our company details, address, and legal disclosures as required by law.",
|
||||
"keywords": "Imprint, Legal Notice, AllYouCanGET, Sinn Consulting, Impressum, contact information, legal disclosure, company details",
|
||||
"og_description": "Official imprint and legal information for AllYouCanGET - Sinn Consulting. Includes company details and contact information."
|
||||
}
|
||||
},
|
||||
"terms_and_conditions.html": {
|
||||
"name": "Terms",
|
||||
"url": "terms_and_conditions.html",
|
||||
"active": "False",
|
||||
"page_title": "Terms and Conditions",
|
||||
"page_subtitle": "AllYouCanGET Consulting Services",
|
||||
"page_cta": "Contact Us",
|
||||
"page_cta_url": "#contact-form",
|
||||
"meta": {
|
||||
"title": "Terms and Conditions | AllYouCanGET",
|
||||
"description": "Read the terms and conditions for using AllYouCanGET consulting services. Understand your rights and obligations when engaging with our IT and management consulting solutions.",
|
||||
"keywords": "Terms and Conditions, AllYouCanGET, Consulting Services, IT Consulting, Management Consulting, Legal Terms, User Agreement, Service Agreement",
|
||||
"og_description": "Review the terms and conditions for AllYouCanGET consulting services. Know your rights and responsibilities."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
## Canonicalization and security headers
|
||||
## ------------------------------------
|
||||
|
||||
## Enable rewrite engine
|
||||
RewriteEngine On
|
||||
|
||||
## 1) Canonical host: redirect www -> apex (always to HTTPS)
|
||||
RewriteCond %{HTTP_HOST} ^www\.allucanget\.biz$ [NC]
|
||||
RewriteRule ^ https://allucanget.biz%{REQUEST_URI} [R=301,L]
|
||||
|
||||
## 2) Force HTTPS (works for direct HTTPS and when behind proxies setting X-Forwarded-Proto)
|
||||
RewriteCond %{HTTPS} !=on [OR]
|
||||
RewriteCond %{HTTP:X-Forwarded-Proto} !https
|
||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
## 3) Security headers
|
||||
<IfModule mod_headers.c>
|
||||
# HSTS: one year, include subdomains (enable after HTTPS is configured everywhere)
|
||||
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
|
||||
|
||||
# Clickjacking protection (also enforced via CSP frame-ancestors)
|
||||
Header set X-Frame-Options "SAMEORIGIN"
|
||||
|
||||
# MIME sniffing protection
|
||||
Header set X-Content-Type-Options "nosniff"
|
||||
|
||||
# Referrer policy
|
||||
Header set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
|
||||
# Lock down powerful features not in use
|
||||
Header set Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()"
|
||||
|
||||
# Content Security Policy tuned for local assets + jsdelivr Tailwind CDN
|
||||
Header set Content-Security-Policy "object-src 'none'; frame-ancestors 'self'; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; upgrade-insecure-requests; block-all-mixed-content"
|
||||
Header set Content-Security-Policy "default-src *.allucanget.biz; base-uri 'self'; script-src 'self' 'unsafe-inline' https://contact.allucanget.biz https://cdn.jsdelivr.net https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline' https://contact.allucanget.biz https://cdn.jsdelivr.net https://static.cloudflareinsights.com; img-src 'self' data: https:; form-action https://contact.allucanget.biz; connect-src 'self' https://contact.allucanget.biz;"
|
||||
</IfModule>
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Redirect the root URL ("/") to the canonical file "index.html"
|
||||
# ------------------------------------------------------------------
|
||||
RewriteRule ^$ /index.html [L]
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Internally rewrite clean URLs like "/about" → "about.html"
|
||||
# ------------------------------------------------------------------
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^([^/]+)/?$ $1.html [L]
|
||||
|
||||
# ensure charset encoding is UTF-8 for all content
|
||||
AddDefaultCharset UTF-8
|
||||
|
||||
# BEGIN cPanel-generated php ini directives, do not edit
|
||||
# Manual editing of this file may result in unexpected behavior.
|
||||
# To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
|
||||
# For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
|
||||
<IfModule php5_module>
|
||||
php_flag asp_tags Off
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30
|
||||
php_value max_input_time 60
|
||||
php_value max_input_vars 1000
|
||||
php_value memory_limit 64M
|
||||
php_value post_max_size 16M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php56"
|
||||
php_value upload_max_filesize 16M
|
||||
php_flag zlib.output_compression Off
|
||||
</IfModule>
|
||||
<IfModule lsapi_module>
|
||||
php_flag asp_tags Off
|
||||
php_flag display_errors Off
|
||||
php_value max_execution_time 30
|
||||
php_value max_input_time 60
|
||||
php_value max_input_vars 1000
|
||||
php_value memory_limit 64M
|
||||
php_value post_max_size 16M
|
||||
php_value session.gc_maxlifetime 1440
|
||||
php_value session.save_path "/var/cpanel/php/sessions/ea-php56"
|
||||
php_value upload_max_filesize 16M
|
||||
php_flag zlib.output_compression Off
|
||||
</IfModule>
|
||||
# END cPanel-generated php ini directives, do not edit
|
||||
@@ -0,0 +1,565 @@
|
||||
/* Color Palette and Typography */
|
||||
|
||||
/* Global Styles */
|
||||
:root {
|
||||
--primary: #10263d;
|
||||
--secondary: #1b3c52;
|
||||
--tertiary: #2f74ad;
|
||||
--quaternary: #a3523f;
|
||||
--quinary: #d9834d;
|
||||
--white: #ffffff;
|
||||
--black: var(--primary);
|
||||
--black-translucent: rgba(16, 38, 61, 0.55);
|
||||
--black-translucent-hover: rgba(16, 38, 61, 0.75);
|
||||
--color-background: var(--primary);
|
||||
--color-text: var(--primary);
|
||||
--color-text-inverse: var(--white);
|
||||
--color-link: #1f5f96;
|
||||
--color-link-hover: #174875;
|
||||
--color-link-inverse: var(--secondary);
|
||||
--color-background-inverse: var(--white);
|
||||
--color-muted: #e8eef6;
|
||||
--color-muted-hover-bg: #2b5677;
|
||||
--header-start: #0b8f69;
|
||||
--header-end: #083f76;
|
||||
--hero-start: #087f5d;
|
||||
--hero-end: #062f5c;
|
||||
--color-gray-50: oklch(98.5% 0.002 247.839);
|
||||
--color-gray-dark: var(--primary);
|
||||
--color-gray-medium-dark: var(--secondary);
|
||||
--color-border-faint: rgba(255, 255, 255, 0.72);
|
||||
--color-input-border: #a8b6c7;
|
||||
--bg-inverse: var(--secondary);
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
|
||||
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
line-height: 1.3;
|
||||
color: var(--color-text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
a {
|
||||
color: var(--color-link);
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover {
|
||||
color: var(--color-link-hover);
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:focus-visible,
|
||||
button:focus-visible,
|
||||
input:focus-visible,
|
||||
textarea:focus-visible {
|
||||
outline: 2px solid var(--quinary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
svg {
|
||||
max-width: 64px;
|
||||
max-height: 64px;
|
||||
}
|
||||
img,
|
||||
video,
|
||||
iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
min-height: 440px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
h2 img {
|
||||
display: inline;
|
||||
max-height: 1.5em;
|
||||
min-height: 1.5em;
|
||||
vertical-align: middle;
|
||||
/* position left of text */
|
||||
}
|
||||
h3 img {
|
||||
display: inline;
|
||||
max-height: 1.2em;
|
||||
min-height: 1.2em;
|
||||
vertical-align: middle;
|
||||
/* position left of text */
|
||||
}
|
||||
#header {
|
||||
/*background-color: var(--color-gray-medium-dark);*/
|
||||
background: linear-gradient(120deg, var(--header-start), var(--header-end));
|
||||
color: var(--white);
|
||||
padding: 1rem 1rem 2rem 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#page-title {
|
||||
width: 100%;
|
||||
}
|
||||
.page-title-header {
|
||||
font-size: clamp(1.6rem, 4.5vw, 2.5rem);
|
||||
line-height: 1.2;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.page-subtitle {
|
||||
font-size: clamp(1rem, 3.4vw, 1.5rem);
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.header-cta {
|
||||
margin-top: 1rem;
|
||||
padding-inline: 1.5rem;
|
||||
}
|
||||
.header-cta-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
#site-navigation {
|
||||
color: var(--white);
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
}
|
||||
#site-navigation-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
min-height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
#site-navigation-content {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
#site-navigation-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
min-width: 0;
|
||||
}
|
||||
#site-navigation-brand {
|
||||
flex-shrink: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
a.site-home-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--white);
|
||||
text-decoration: none;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
gap: 0.75rem;
|
||||
transition: opacity 0.2s ease;
|
||||
min-width: 0;
|
||||
}
|
||||
a.site-home-link:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.nav-logo {
|
||||
height: 50px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
.nav-text {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.hamburger-menu {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
z-index: 1001;
|
||||
}
|
||||
.hamburger-line {
|
||||
width: 30px;
|
||||
height: 3px;
|
||||
background: var(--white);
|
||||
border-radius: 2px;
|
||||
transition: all 0.3s ease;
|
||||
transform-origin: center;
|
||||
}
|
||||
.nav-menu {
|
||||
display: flex;
|
||||
}
|
||||
#site-nav-links {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
a.site-nav-link {
|
||||
color: var(--color-muted);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
a.site-nav-link:hover {
|
||||
color: var(--white);
|
||||
background-color: var(--color-muted-hover-bg);
|
||||
}
|
||||
a.site-nav-link.active {
|
||||
color: var(--white);
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
#main-content {
|
||||
padding-top: 0;
|
||||
}
|
||||
#main {
|
||||
background-color: var(--white);
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
border: 0 solid;
|
||||
}
|
||||
.bigbutton {
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
background: linear-gradient(135deg, var(--quaternary), var(--quinary));
|
||||
color: var(--white);
|
||||
margin-top: 0.5rem;
|
||||
border: 1px solid var(--color-border-faint);
|
||||
}
|
||||
.bigbutton:hover {
|
||||
background: linear-gradient(135deg, #934332, #c86f3a);
|
||||
color: var(--white);
|
||||
border-color: var(--white);
|
||||
}
|
||||
.bigbutton a {
|
||||
color: var(--white);
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.bigbutton a:hover {
|
||||
color: var(--white);
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
border-color: var(--white);
|
||||
}
|
||||
.bigbutton a span:last-of-type {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
#hero {
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--hero-start),
|
||||
var(--hero-end)
|
||||
);
|
||||
color: var(--white);
|
||||
padding: 4rem 0;
|
||||
}
|
||||
#hero .container {
|
||||
text-align: left;
|
||||
}
|
||||
#hero h1 {
|
||||
font-size: clamp(1.35rem, 4vw, 2rem);
|
||||
line-height: 1.2;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
#hero p {
|
||||
font-size: clamp(1rem, 3vw, 1.5rem);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.section {
|
||||
background-color: var(--white);
|
||||
padding-block: 3rem;
|
||||
}
|
||||
.section:nth-last-child(4) {
|
||||
min-height: 300px;
|
||||
height: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.section:nth-last-child(5) {
|
||||
min-height: 300px;
|
||||
height: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.section-container {
|
||||
padding-inline: 1rem;
|
||||
margin-inline: auto;
|
||||
}
|
||||
.section h2 {
|
||||
font-size: clamp(1.3rem, 4vw, 2.25rem);
|
||||
font-weight: bold;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.section-content {
|
||||
font-size: clamp(1rem, 2.3vw, 1.125rem);
|
||||
color: var(--color-text);
|
||||
margin-bottom: 1rem;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.section-content hr {
|
||||
max-width: 80%;
|
||||
margin: 3rem auto 1rem auto;
|
||||
}
|
||||
.section-cards {
|
||||
display: grid;
|
||||
gap: 2rem;
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
|
||||
}
|
||||
.section-card {
|
||||
background-color: var(--white);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
.section-card:hover {
|
||||
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.section-card-title {
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.section-card-detail {
|
||||
background-color: var(--color-background-inverse);
|
||||
border-radius: 0.375rem;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
img[src*="img/partner/"] {
|
||||
max-width: 200px;
|
||||
max-height: 100px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
margin: 2rem auto;
|
||||
}
|
||||
img[src*="img/partner/"].hidden {
|
||||
max-width: 200px;
|
||||
max-height: 100px;
|
||||
display: none;
|
||||
}
|
||||
#call-to-action {
|
||||
background: linear-gradient(120deg, #0a8e67, #073b70);
|
||||
color: var(--white);
|
||||
margin-top: 0;
|
||||
padding: 3rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
#cta-container {
|
||||
max-width: 800px;
|
||||
padding: 0 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
#cta-container iframe {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
min-height: 520px;
|
||||
}
|
||||
#contact-form {
|
||||
display: block;
|
||||
max-width: 600px;
|
||||
max-height: 600px;
|
||||
margin: 0 auto;
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
#contact-form input,
|
||||
#contact-form textarea {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid var(--color-input-border);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
#contact-form textarea {
|
||||
height: 150px;
|
||||
}
|
||||
#footer {
|
||||
background-color: var(--color-background);
|
||||
color: var(--quaternary);
|
||||
padding: 2rem 0;
|
||||
text-align: center;
|
||||
display: block;
|
||||
}
|
||||
.footer-link {
|
||||
color: var(--quinary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
#services {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
width: min(100%, 1200px);
|
||||
max-width: 100%;
|
||||
padding-inline: 1rem;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
#header {
|
||||
padding: 0;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
h1, h1.page-title-header, #hero h1 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
.page-subtitle {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.section h2 {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
.section-content {
|
||||
font-size: 1rem;
|
||||
}
|
||||
#page-title {
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
#hero {
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0 0.9rem;
|
||||
}
|
||||
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
#site-navigation-container {
|
||||
padding: 0 1rem;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
#site-navigation-bar {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
a.site-home-link {
|
||||
font-size: 1.25rem;
|
||||
gap: 0.5rem;
|
||||
max-width: calc(100% - 44px);
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.hamburger-menu {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: var(--color-gray-dark);
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 60px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.nav-menu.open {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#site-nav-links {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
a.site-nav-link {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
margin: 0.25rem 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
a.site-nav-link:hover {
|
||||
background-color: var(--color-muted-hover-bg);
|
||||
}
|
||||
|
||||
/* Hamburger animation */
|
||||
.hamburger-menu.open .hamburger-line:nth-child(1) {
|
||||
transform: rotate(45deg) translate(6px, 6px);
|
||||
}
|
||||
|
||||
.hamburger-menu.open .hamburger-line:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hamburger-menu.open .hamburger-line:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(6px, -6px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 420px) {
|
||||
.nav-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a.site-home-link {
|
||||
max-width: calc(100% - 40px);
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 374 B |
@@ -0,0 +1 @@
|
||||
google-site-verification: google8753946d6666aa9a.html
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
@@ -0,0 +1,13 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<line x1="12" x2="12" y1="20" y2="10"></line>
|
||||
<line x1="18" x2="18" y1="20" y2="4"></line>
|
||||
<line x1="6" x2="6" y1="20" y2="16"></line>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 378 B |
@@ -0,0 +1,10 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M6 16.326A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 .5 8.973"/>
|
||||
<path d="m13 12-3 5h4l-3 5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 327 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 372 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 462 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 390 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 374 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#2563eb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 362 B |
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect>
|
||||
<rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect>
|
||||
<line x1="6" x2="6.01" y1="6" y2="6"></line>
|
||||
<line x1="6" x2="6.01" y1="18" y2="18"></line>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 465 B |
@@ -0,0 +1,11 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 412 B |
@@ -0,0 +1,12 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"></polyline>
|
||||
<polyline points="16 7 22 7 22 13"></polyline>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 338 B |
@@ -0,0 +1,13 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="16" y="16" width="6" height="6" rx="1"/>
|
||||
<rect x="2" y="16" width="6" height="6" rx="1"/>
|
||||
<rect x="9" y="2" width="6" height="6" rx="1"/>
|
||||
<path d="M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3"/>
|
||||
<path d="M12 12V8"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 462 B |
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 304 182" style="enable-background:new 0 0 304 182;" xml:space="preserve"><script xmlns=""/>
|
||||
<style type="text/css">
|
||||
.st0{fill:#252F3E;}
|
||||
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FF9900;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M86.4,66.4c0,3.7,0.4,6.7,1.1,8.9c0.8,2.2,1.8,4.6,3.2,7.2c0.5,0.8,0.7,1.6,0.7,2.3c0,1-0.6,2-1.9,3l-6.3,4.2 c-0.9,0.6-1.8,0.9-2.6,0.9c-1,0-2-0.5-3-1.4C76.2,90,75,88.4,74,86.8c-1-1.7-2-3.6-3.1-5.9c-7.8,9.2-17.6,13.8-29.4,13.8 c-8.4,0-15.1-2.4-20-7.2c-4.9-4.8-7.4-11.2-7.4-19.2c0-8.5,3-15.4,9.1-20.6c6.1-5.2,14.2-7.8,24.5-7.8c3.4,0,6.9,0.3,10.6,0.8 c3.7,0.5,7.5,1.3,11.5,2.2v-7.3c0-7.6-1.6-12.9-4.7-16c-3.2-3.1-8.6-4.6-16.3-4.6c-3.5,0-7.1,0.4-10.8,1.3c-3.7,0.9-7.3,2-10.8,3.4 c-1.6,0.7-2.8,1.1-3.5,1.3c-0.7,0.2-1.2,0.3-1.6,0.3c-1.4,0-2.1-1-2.1-3.1v-4.9c0-1.6,0.2-2.8,0.7-3.5c0.5-0.7,1.4-1.4,2.8-2.1 c3.5-1.8,7.7-3.3,12.6-4.5c4.9-1.3,10.1-1.9,15.6-1.9c11.9,0,20.6,2.7,26.2,8.1c5.5,5.4,8.3,13.6,8.3,24.6V66.4z M45.8,81.6 c3.3,0,6.7-0.6,10.3-1.8c3.6-1.2,6.8-3.4,9.5-6.4c1.6-1.9,2.8-4,3.4-6.4c0.6-2.4,1-5.3,1-8.7v-4.2c-2.9-0.7-6-1.3-9.2-1.7 c-3.2-0.4-6.3-0.6-9.4-0.6c-6.7,0-11.6,1.3-14.9,4c-3.3,2.7-4.9,6.5-4.9,11.5c0,4.7,1.2,8.2,3.7,10.6 C37.7,80.4,41.2,81.6,45.8,81.6z M126.1,92.4c-1.8,0-3-0.3-3.8-1c-0.8-0.6-1.5-2-2.1-3.9L96.7,10.2c-0.6-2-0.9-3.3-0.9-4 c0-1.6,0.8-2.5,2.4-2.5h9.8c1.9,0,3.2,0.3,3.9,1c0.8,0.6,1.4,2,2,3.9l16.8,66.2l15.6-66.2c0.5-2,1.1-3.3,1.9-3.9c0.8-0.6,2.2-1,4-1 h8c1.9,0,3.2,0.3,4,1c0.8,0.6,1.5,2,1.9,3.9l15.8,67l17.3-67c0.6-2,1.3-3.3,2-3.9c0.8-0.6,2.1-1,3.9-1h9.3c1.6,0,2.5,0.8,2.5,2.5 c0,0.5-0.1,1-0.2,1.6c-0.1,0.6-0.3,1.4-0.7,2.5l-24.1,77.3c-0.6,2-1.3,3.3-2.1,3.9c-0.8,0.6-2.1,1-3.8,1h-8.6c-1.9,0-3.2-0.3-4-1 c-0.8-0.7-1.5-2-1.9-4L156,23l-15.4,64.4c-0.5,2-1.1,3.3-1.9,4c-0.8,0.7-2.2,1-4,1H126.1z M254.6,95.1c-5.2,0-10.4-0.6-15.4-1.8 c-5-1.2-8.9-2.5-11.5-4c-1.6-0.9-2.7-1.9-3.1-2.8c-0.4-0.9-0.6-1.9-0.6-2.8v-5.1c0-2.1,0.8-3.1,2.3-3.1c0.6,0,1.2,0.1,1.8,0.3 c0.6,0.2,1.5,0.6,2.5,1c3.4,1.5,7.1,2.7,11,3.5c4,0.8,7.9,1.2,11.9,1.2c6.3,0,11.2-1.1,14.6-3.3c3.4-2.2,5.2-5.4,5.2-9.5 c0-2.8-0.9-5.1-2.7-7c-1.8-1.9-5.2-3.6-10.1-5.2L246,52c-7.3-2.3-12.7-5.7-16-10.2c-3.3-4.4-5-9.3-5-14.5c0-4.2,0.9-7.9,2.7-11.1 c1.8-3.2,4.2-6,7.2-8.2c3-2.3,6.4-4,10.4-5.2c4-1.2,8.2-1.7,12.6-1.7c2.2,0,4.5,0.1,6.7,0.4c2.3,0.3,4.4,0.7,6.5,1.1 c2,0.5,3.9,1,5.7,1.6c1.8,0.6,3.2,1.2,4.2,1.8c1.4,0.8,2.4,1.6,3,2.5c0.6,0.8,0.9,1.9,0.9,3.3v4.7c0,2.1-0.8,3.2-2.3,3.2 c-0.8,0-2.1-0.4-3.8-1.2c-5.7-2.6-12.1-3.9-19.2-3.9c-5.7,0-10.2,0.9-13.3,2.8c-3.1,1.9-4.7,4.8-4.7,8.9c0,2.8,1,5.2,3,7.1 c2,1.9,5.7,3.8,11,5.5l14.2,4.5c7.2,2.3,12.4,5.5,15.5,9.6c3.1,4.1,4.6,8.8,4.6,14c0,4.3-0.9,8.2-2.6,11.6 c-1.8,3.4-4.2,6.4-7.3,8.8c-3.1,2.5-6.8,4.3-11.1,5.6C264.4,94.4,259.7,95.1,254.6,95.1z"/>
|
||||
<g>
|
||||
<path class="st1" d="M273.5,143.7c-32.9,24.3-80.7,37.2-121.8,37.2c-57.6,0-109.5-21.3-148.7-56.7c-3.1-2.8-0.3-6.6,3.4-4.4 c42.4,24.6,94.7,39.5,148.8,39.5c36.5,0,76.6-7.6,113.5-23.2C274.2,133.6,278.9,139.7,273.5,143.7z"/>
|
||||
<path class="st1" d="M287.2,128.1c-4.2-5.4-27.8-2.6-38.5-1.3c-3.2,0.4-3.7-2.4-0.8-4.5c18.8-13.2,49.7-9.4,53.3-5 c3.6,4.5-1,35.4-18.6,50.2c-2.7,2.3-5.3,1.1-4.1-1.9C282.5,155.7,291.4,133.4,287.2,128.1z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 272 92" width="272" height="92"><script xmlns=""/><path fill="#EA4335" d="M115.75 47.18c0 12.77-9.99 22.18-22.25 22.18s-22.25-9.41-22.25-22.18C71.25 34.32 81.24 25 93.5 25s22.25 9.32 22.25 22.18zm-9.74 0c0-7.98-5.79-13.44-12.51-13.44S80.99 39.2 80.99 47.18c0 7.9 5.79 13.44 12.51 13.44s12.51-5.55 12.51-13.44z"/><path fill="#FBBC05" d="M163.75 47.18c0 12.77-9.99 22.18-22.25 22.18s-22.25-9.41-22.25-22.18c0-12.85 9.99-22.18 22.25-22.18s22.25 9.32 22.25 22.18zm-9.74 0c0-7.98-5.79-13.44-12.51-13.44s-12.51 5.46-12.51 13.44c0 7.9 5.79 13.44 12.51 13.44s12.51-5.55 12.51-13.44z"/><path fill="#4285F4" d="M209.75 26.34v39.82c0 16.38-9.66 23.07-21.08 23.07-10.75 0-17.22-7.19-19.66-13.07l8.48-3.53c1.51 3.61 5.21 7.87 11.17 7.87 7.31 0 11.84-4.51 11.84-13v-3.19h-.34c-2.18 2.69-6.38 5.04-11.68 5.04-11.09 0-21.25-9.66-21.25-22.09 0-12.52 10.16-22.26 21.25-22.26 5.29 0 9.49 2.35 11.68 4.96h.34v-3.61h9.25zm-8.56 20.92c0-7.81-5.21-13.52-11.84-13.52-6.72 0-12.35 5.71-12.35 13.52 0 7.73 5.63 13.36 12.35 13.36 6.63 0 11.84-5.63 11.84-13.36z"/><path fill="#34A853" d="M225 3v65h-9.5V3h9.5z"/><path fill="#EA4335" d="M262.02 54.48l7.56 5.04c-2.44 3.61-8.32 9.83-18.48 9.83-12.6 0-22.01-9.74-22.01-22.18 0-13.19 9.49-22.18 20.92-22.18 11.51 0 17.14 9.16 18.98 14.11l1.01 2.52-29.65 12.28c2.27 4.45 5.8 6.72 10.75 6.72 4.96 0 8.4-2.44 10.92-6.14zm-23.27-7.98l19.82-8.23c-1.09-2.77-4.37-4.7-8.23-4.7-4.95 0-11.84 4.37-11.59 12.93z"/><path fill="#4285F4" d="M35.29 41.41V32H67c.31 1.64.47 3.58.47 5.68 0 7.06-1.93 15.79-8.15 22.01-6.05 6.3-13.78 9.66-24.02 9.66C16.32 69.35.36 53.89.36 34.91.36 15.93 16.32.47 35.3.47c10.5 0 17.98 4.12 23.6 9.49l-6.64 6.64c-4.03-3.78-9.49-6.72-16.97-6.72-13.86 0-24.7 11.17-24.7 25.03 0 13.86 10.84 25.03 24.7 25.03 8.99 0 14.11-3.61 17.39-6.89 2.66-2.66 4.41-6.46 5.1-11.65l-22.49.01z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,40 @@
|
||||
<svg version="1.2" baseProfile="tiny-ps" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1607 401" width="1607" height="401">
|
||||
<title>logo-informatica-svg</title>
|
||||
<style>
|
||||
tspan { white-space:pre }
|
||||
.shp0 { fill: #ff4d00 }
|
||||
.shp1 { fill: #ff7d00 }
|
||||
.shp2 { fill: #001aff }
|
||||
.shp3 { fill: #e23400 }
|
||||
.shp4 { fill: #373737 }
|
||||
</style>
|
||||
<g id="logo-informatica">
|
||||
<g id="Logo/Informatica">
|
||||
<g id="Group-32">
|
||||
<g id="Layer">
|
||||
<path id="Fill-1" class="shp0" d="M218.7 205.64L267.31 213.77L300.25 249.32L295.83 300.43L177.19 233.21L218.7 205.64Z" />
|
||||
<path id="Fill-2" class="shp1" d="M394.43 200.52L295.83 300.44L197.21 0.69L394.43 200.52Z" />
|
||||
<path id="Fill-3" class="shp2" d="M328.73 200.52L177.19 233.21L181.35 159.45L328.73 200.52Z" />
|
||||
<path id="Fill-4" class="shp3" d="M0 200.53L73.06 216.86L121.39 248.63L124.91 280.61L105.3 307.22L0 200.53Z" />
|
||||
<path id="Fill-5" class="shp0" d="M186.55 11.51L121.38 248.63L0 200.53L186.55 11.51Z" />
|
||||
<path id="Fill-6" class="shp1" d="M121.39 248.63L283.58 312.85L197.21 400.36L105.3 307.22L121.39 248.63Z" />
|
||||
<path id="Fill-7" class="shp4" d="M525.69 257.51L507.24 257.51L507.24 106.29L525.69 95.39L525.69 257.51Z" />
|
||||
<path id="Fill-8" class="shp4" d="M1351.23 122.81L1332.26 122.81L1332.26 107.95L1332.26 102.75L1351.23 102.75L1351.23 122.81Z" />
|
||||
<g id="Group-31">
|
||||
<path id="Fill-9" fill-rule="evenodd" class="shp4" d="M638.75 153.75C645.9 161.89 649.68 173.34 649.68 186.9L649.68 257.51L631.64 257.51L631.64 191C631.64 170.62 621.17 158.44 603.64 158.44C585.71 158.44 573.18 172.36 573.18 192.3L573.18 257.51L555.15 257.51L555.15 143.33L573.18 143.33L573.18 159.87C581.6 147.3 593.33 140.94 608.13 140.94C620.8 140.94 631.39 145.36 638.75 153.75Z" />
|
||||
<path id="Fill-11" fill-rule="evenodd" class="shp4" d="M849.57 200.09L849.57 200.52C849.57 216.32 843.88 231.19 833.55 242.37C822.99 253.81 808.62 260.11 793.13 260.11C761.82 260.11 737.29 234.12 737.29 200.96L737.29 200.52C737.29 184.7 742.94 169.85 753.21 158.68C763.72 147.24 778.04 140.94 793.53 140.94C824.95 140.94 849.57 166.93 849.57 200.09ZM793.13 158.01C771.81 158.01 755.73 176.1 755.73 200.09L755.73 200.52C755.73 224.25 772.34 242.83 793.53 242.83C814.96 242.83 831.13 224.82 831.13 200.96L831.13 200.52C831.13 176.69 814.43 158.01 793.13 158.01Z" />
|
||||
<path id="Fill-13" fill-rule="evenodd" class="shp4" d="M931.47 141.38L932.59 141.43L932.59 160.93L930.21 160.93C905.51 160.93 889.55 181.34 889.55 211.77L889.55 257.51L871.52 257.51L871.52 143.32L889.55 143.32L889.55 168.41C898.64 150.63 914.01 140.61 931.47 141.38Z" />
|
||||
<path id="Fill-15" fill-rule="evenodd" class="shp4" d="M1112.3 187.11L1112.3 257.51L1094.27 257.51L1094.27 191C1094.27 170.32 1084.74 158.44 1068.1 158.44C1060.43 158.44 1053.48 161.51 1048.51 167.08C1043.14 173.11 1040.3 181.69 1040.3 191.87L1040.3 257.51L1022.26 257.51L1022.26 190.57C1022.26 170.45 1012.55 158.44 996.29 158.44C979.95 158.44 968.08 172.77 968.08 192.52L968.08 257.51L950.05 257.51L950.05 143.33L968.08 143.33L968.08 159.43C974.47 150.22 984.04 140.94 1000.99 140.94C1016.06 140.94 1028.07 148.4 1034.99 162C1044.26 147.83 1056.38 140.94 1071.97 140.94C1096.85 140.94 1112.3 158.63 1112.3 187.11Z" />
|
||||
<path id="Fill-17" fill-rule="evenodd" class="shp4" d="M1276.51 160.39L1276.51 224.54C1276.51 236.26 1281.93 241.96 1293.1 241.96C1298.35 241.96 1302.63 240.86 1307.87 238.19L1309.55 237.33L1309.55 254.22L1308.95 254.56C1302.87 257.9 1296.67 259.46 1289.42 259.46C1277.86 259.46 1258.47 255.2 1258.47 226.69L1258.47 160.39L1238.84 160.39L1238.84 143.32L1258.47 143.32L1258.47 114.23L1276.51 103.57L1276.51 143.32L1310.38 143.32L1310.38 160.39L1276.51 160.39Z" />
|
||||
<path id="Fill-19" fill-rule="evenodd" class="shp4" d="M1460.95 225.64L1472.59 237.23L1471.89 238.06C1463.21 248.32 1450.37 260.11 1427.96 260.11C1412.9 260.11 1398.9 253.85 1388.53 242.5C1378.35 231.36 1372.74 216.61 1372.74 200.96L1372.74 200.52C1372.74 184.76 1378.35 169.9 1388.53 158.68C1398.9 147.24 1412.9 140.94 1427.96 140.94C1450.19 140.94 1462.67 151.79 1471.05 161.23L1471.75 162.02L1459.79 175.45L1458.92 174.5C1451.22 165.93 1442.12 158.01 1427.76 158.01C1407.25 158.01 1391.18 176.49 1391.18 200.09L1391.18 200.52C1391.18 224.25 1407.69 242.82 1428.77 242.82C1440.26 242.82 1450.52 237.51 1460.14 226.56L1460.95 225.64Z" />
|
||||
<path id="Fill-21" fill-rule="evenodd" class="shp4" d="M1180.9 140.94C1196.12 140.94 1207.86 145.21 1215.8 153.64C1223.19 161.47 1226.94 173.6 1226.94 187.98L1226.94 257.51L1209.72 257.51L1209.72 242.87C1202.85 251.18 1191.02 259.89 1172.53 259.89C1152.39 259.89 1132.01 247.52 1132.01 223.88L1132.01 223.45C1132.01 200.8 1148.85 187.82 1178.25 187.82L1209.72 187.82C1209.72 167.01 1198.65 158.01 1179.27 158.01C1166.21 158.01 1156.41 161.91 1147.74 166.11L1146.57 166.68L1141.11 150.81L1142.05 150.36C1151.68 145.7 1163.82 140.94 1180.9 140.94ZM1179.88 202.51C1155.38 202.51 1150.24 213.54 1150.24 222.8L1150.24 223.24C1150.24 233.4 1158.17 244.34 1175.6 244.34C1195.05 244.34 1209.72 231.82 1209.72 215.23L1209.72 202.51L1179.88 202.51Z" />
|
||||
<path id="Fill-23" fill-rule="evenodd" class="shp4" d="M700.68 143.32L734.54 143.32L734.54 160.38L700.68 160.38L700.68 257.51L682.64 257.51L682.64 160.38L663.01 160.38L663.01 143.32L682.64 143.32L682.64 131.82C682.64 119.06 685.93 108.85 692.14 102.26C697.7 96.36 705.82 93.24 715.61 93.24C722.84 93.24 727.98 94.08 733.35 96.13L733.72 96.27L733.72 113.18L732.61 112.85C726.56 111.02 722.59 110.09 717.65 110.09C704.84 110.09 700.68 116.25 700.68 132.68L700.68 143.32Z" />
|
||||
<path id="Fill-25" class="shp4" d="M1350.76 257.51L1332.73 257.51L1332.73 155.47L1332.73 143.32L1350.76 143.32L1350.76 257.51Z" />
|
||||
<path id="Fill-27" fill-rule="evenodd" class="shp4" d="M1532.62 140.94C1547.83 140.94 1559.58 145.21 1567.52 153.64C1574.91 161.47 1578.66 173.6 1578.66 187.99L1578.66 257.53L1561.43 257.53L1561.44 242.88C1554.56 251.19 1542.74 259.9 1524.25 259.9C1504.1 259.9 1483.71 247.53 1483.71 223.89L1483.71 223.46C1483.71 200.81 1500.56 187.83 1529.96 187.83L1561.44 187.83C1561.44 167.02 1550.37 158.01 1530.98 158.01C1517.93 158.01 1508.12 161.91 1499.45 166.12L1498.29 166.68L1492.81 150.81L1493.76 150.36C1503.39 145.7 1515.53 140.94 1532.62 140.94ZM1531.59 202.52C1507.09 202.52 1501.95 213.55 1501.95 222.81L1501.95 223.25C1501.95 233.41 1509.88 244.35 1527.31 244.35C1546.77 244.35 1561.44 231.84 1561.44 215.24L1561.44 202.52L1531.59 202.52Z" />
|
||||
<path id="Fill-29" fill-rule="evenodd" class="shp4" d="M1586.67 147.9C1587.58 146.18 1588.86 144.82 1590.48 143.83C1592.11 142.84 1593.87 142.34 1595.76 142.34C1597.65 142.34 1599.39 142.84 1601.02 143.83C1602.64 144.82 1603.91 146.18 1604.83 147.9C1605.75 149.62 1606.2 151.48 1606.2 153.49C1606.2 155.46 1605.76 157.3 1604.88 159.01C1604 160.72 1602.74 162.1 1601.12 163.14C1599.49 164.18 1597.71 164.7 1595.76 164.7C1593.82 164.7 1592.04 164.19 1590.42 163.15C1588.78 162.12 1587.53 160.75 1586.63 159.03C1585.74 157.32 1585.29 155.48 1585.29 153.49C1585.29 151.48 1585.75 149.62 1586.67 147.9ZM1588.16 158.25C1588.95 159.7 1590.02 160.85 1591.37 161.67C1592.73 162.5 1594.18 162.9 1595.76 162.9C1597.34 162.9 1598.81 162.49 1600.16 161.64C1601.52 160.8 1602.58 159.66 1603.35 158.22C1604.12 156.78 1604.51 155.2 1604.51 153.49C1604.51 151.79 1604.12 150.22 1603.35 148.78C1602.58 147.34 1601.52 146.21 1600.16 145.38C1598.81 144.55 1597.34 144.14 1595.76 144.14C1594.18 144.14 1592.72 144.54 1591.36 145.36C1590.01 146.19 1588.93 147.32 1588.16 148.77C1587.38 150.23 1586.99 151.8 1586.99 153.49C1586.99 155.2 1587.38 156.78 1588.16 158.25ZM1593.59 154.62L1593.59 159.66L1591.51 159.66L1591.51 146.98L1595.58 146.98C1597.08 146.98 1598.25 147.31 1599.08 147.96C1599.91 148.62 1600.32 149.56 1600.32 150.81C1600.32 152.03 1599.7 152.97 1598.44 153.61C1599.63 154.12 1600.24 155.13 1600.26 156.67L1600.26 157.57C1600.26 158.43 1600.34 159.05 1600.5 159.43L1600.5 159.66L1598.37 159.66C1598.23 159.31 1598.16 158.66 1598.16 157.75C1598.16 156.83 1598.14 156.28 1598.11 156.11C1597.95 155.16 1597.32 154.65 1596.18 154.62L1593.59 154.62ZM1593.59 152.71L1595.89 152.71C1596.6 152.69 1597.17 152.51 1597.6 152.19C1598.04 151.86 1598.24 151.43 1598.24 150.89C1598.24 150.16 1598.06 149.65 1597.67 149.35C1597.29 149.05 1596.6 148.9 1595.63 148.9L1593.59 148.9L1593.59 152.71Z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.2 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 337.6 72"><script xmlns=""/>
|
||||
<path fill="#737373" d="M140.4,14.4v43.2h-7.5V23.7h-0.1l-13.4,33.9h-5l-13.7-33.9h-0.1v33.9h-6.9V14.4h10.8l12.4,32h0.2l13.1-32H140.4 z M146.6,17.7c0-1.2,0.4-2.2,1.3-3c0.9-0.8,1.9-1.2,3.1-1.2c1.3,0,2.4,0.4,3.2,1.2s1.3,1.8,1.3,3c0,1.2-0.4,2.2-1.3,3 c-0.9,0.8-1.9,1.2-3.2,1.2s-2.3-0.4-3.1-1.2C147.1,19.8,146.6,18.8,146.6,17.7z M154.7,26.6v31h-7.3v-31H154.7z M176.8,52.3 c1.1,0,2.3-0.2,3.6-0.8c1.3-0.5,2.5-1.2,3.6-2v6.8c-1.2,0.7-2.5,1.2-4,1.5c-1.5,0.3-3.1,0.5-4.9,0.5c-4.6,0-8.3-1.4-11.1-4.3 c-2.9-2.9-4.3-6.6-4.3-11c0-5,1.5-9.1,4.4-12.3c2.9-3.2,7-4.8,12.4-4.8c1.4,0,2.8,0.2,4.1,0.5c1.4,0.3,2.5,0.8,3.3,1.2v7 c-1.1-0.8-2.3-1.5-3.4-1.9c-1.2-0.4-2.4-0.7-3.6-0.7c-2.9,0-5.2,0.9-7,2.8s-2.6,4.4-2.6,7.6c0,3.1,0.9,5.6,2.6,7.3 C171.6,51.4,173.9,52.3,176.8,52.3z M204.7,26.1c0.6,0,1.1,0,1.6,0.1s0.9,0.2,1.2,0.3v7.4c-0.4-0.3-0.9-0.6-1.7-0.8 s-1.6-0.4-2.7-0.4c-1.8,0-3.3,0.8-4.5,2.3s-1.9,3.8-1.9,7v15.6h-7.3v-31h7.3v4.9h0.1c0.7-1.7,1.7-3,3-4 C201.2,26.6,202.8,26.1,204.7,26.1z M207.9,42.6c0-5.1,1.5-9.2,4.3-12.2c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3 s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2C209.3,51.3,207.9,47.4,207.9,42.6z M215.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6 c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C216.2,36.5,215.5,39,215.5,42.3z M250.5,34.8c0,1,0.3,1.9,1,2.5 c0.7,0.6,2.1,1.3,4.4,2.2c2.9,1.2,5,2.5,6.1,3.9c1.2,1.5,1.8,3.2,1.8,5.3c0,2.9-1.1,5.2-3.4,7c-2.2,1.8-5.3,2.6-9.1,2.6 c-1.3,0-2.7-0.2-4.3-0.5c-1.6-0.3-2.9-0.7-4-1.2v-7.2c1.3,0.9,2.8,1.7,4.3,2.2c1.5,0.5,2.9,0.8,4.2,0.8c1.6,0,2.9-0.2,3.6-0.7 c0.8-0.5,1.2-1.2,1.2-2.3c0-1-0.4-1.8-1.2-2.6c-0.8-0.7-2.4-1.5-4.6-2.4c-2.7-1.1-4.6-2.4-5.7-3.8s-1.7-3.2-1.7-5.4 c0-2.8,1.1-5.1,3.3-6.9c2.2-1.8,5.1-2.7,8.6-2.7c1.1,0,2.3,0.1,3.6,0.4s2.5,0.6,3.4,0.9V34c-1-0.6-2.1-1.2-3.4-1.7 c-1.3-0.5-2.6-0.7-3.8-0.7c-1.4,0-2.5,0.3-3.2,0.8C250.9,33.1,250.5,33.8,250.5,34.8z M266.9,42.6c0-5.1,1.5-9.2,4.3-12.2 c2.9-3,6.9-4.5,12-4.5c4.8,0,8.6,1.4,11.3,4.3s4.1,6.8,4.1,11.7c0,5-1.5,9-4.3,12c-2.9,3-6.8,4.5-11.8,4.5c-4.8,0-8.6-1.4-11.4-4.2 C268.4,51.3,266.9,47.4,266.9,42.6z M274.5,42.3c0,3.2,0.7,5.7,2.2,7.4s3.6,2.6,6.3,2.6c2.6,0,4.7-0.8,6.1-2.6 c1.4-1.7,2.1-4.2,2.1-7.6c0-3.3-0.7-5.8-2.1-7.6c-1.4-1.7-3.5-2.6-6-2.6c-2.7,0-4.7,0.9-6.2,2.7C275.3,36.5,274.5,39,274.5,42.3z M322.9,32.6h-10.9v25h-7.4v-25h-5.2v-6h5.2v-4.3c0-3.2,1.1-5.9,3.2-8s4.8-3.1,8.1-3.1c0.9,0,1.7,0.1,2.4,0.1s1.3,0.2,1.8,0.4v6.3 c-0.2-0.1-0.7-0.3-1.3-0.5c-0.6-0.2-1.3-0.3-2.1-0.3c-1.5,0-2.7,0.5-3.5,1.4c-0.8,0.9-1.2,2.4-1.2,4.2v3.7h10.9v-7l7.3-2.2v9.2h7.4 v6h-7.4v14.5c0,1.9,0.4,3.2,1,4c0.7,0.8,1.8,1.2,3.3,1.2c0.4,0,0.9-0.1,1.5-0.3c0.6-0.2,1.1-0.4,1.5-0.7v6c-0.5,0.3-1.2,0.5-2.3,0.7 c-1.1,0.2-2.1,0.3-3.2,0.3c-3.1,0-5.4-0.8-6.9-2.4c-1.5-1.6-2.3-4.1-2.3-7.4L322.9,32.6L322.9,32.6z"/>
|
||||
<rect fill="#F25022" width="34.2" height="34.2"/>
|
||||
<rect x="37.8" fill="#7FBA00" width="34.2" height="34.2"/>
|
||||
<rect y="37.8" fill="#00A4EF" width="34.2" height="34.2"/>
|
||||
<rect x="37.8" y="37.8" fill="#FFB900" width="34.2" height="34.2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 231 30" preserveAspectRatio="xMinYMid"><script xmlns=""/><path d="M99.61,19.52h15.24l-8.05-13L92,30H85.27l18-28.17a4.29,4.29,0,0,1,7-.05L128.32,30h-6.73l-3.17-5.25H103l-3.36-5.23m69.93,5.23V0.28h-5.72V27.16a2.76,2.76,0,0,0,.85,2,2.89,2.89,0,0,0,2.08.87h26l3.39-5.25H169.54M75,20.38A10,10,0,0,0,75,.28H50V30h5.71V5.54H74.65a4.81,4.81,0,0,1,0,9.62H58.54L75.6,30h8.29L72.43,20.38H75M14.88,30H32.15a14.86,14.86,0,0,0,0-29.71H14.88a14.86,14.86,0,1,0,0,29.71m16.88-5.23H15.26a9.62,9.62,0,0,1,0-19.23h16.5a9.62,9.62,0,1,1,0,19.23M140.25,30h17.63l3.34-5.23H140.64a9.62,9.62,0,1,1,0-19.23h16.75l3.38-5.25H140.25a14.86,14.86,0,1,0,0,29.71m69.87-5.23a9.62,9.62,0,0,1-9.26-7h24.42l3.36-5.24H200.86a9.61,9.61,0,0,1,9.26-7h16.76l3.35-5.25h-20.5a14.86,14.86,0,0,0,0,29.71h17.63l3.35-5.23h-20.6" transform="translate(-0.02 0)" style="fill:#C74634"/></svg>
|
||||
|
After Width: | Height: | Size: 892 B |
|
After Width: | Height: | Size: 7.9 KiB |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="743.36707" height="368.43945"><script xmlns=""/>
|
||||
<g transform="translate(-446.7987,535.9143)">
|
||||
<path d="M 446.79872,-168.02763 L 822.11906,-168.02763 L 1190.1658,-535.9143 L 446.79872,-535.9143 L 446.79872,-168.02763" style="fill:#014185;fill-rule:nonzero;stroke:none"/>
|
||||
<path d="M 887.58191,-466.77099 L 814.84541,-466.78553 L 814.84541,-292.77073 L 750.83729,-466.78553 L 688.2839,-466.78553 L 633.00416,-321.25434 C 627.18524,-357.91354 589.36226,-370.58424 558.81293,-380.06908 C 539.90144,-386.4408 518.08049,-395.80926 519.53522,-406.05056 C 519.53522,-414.54618 529.71833,-422.34353 551.53928,-421.17975 C 566.08658,-420.43784 579.17915,-419.23041 605.36429,-406.74883 L 631.54943,-451.07445 C 606.81902,-463.06142 574.81496,-470.64057 548.62982,-470.66966 L 548.62982,-470.66966 C 516.62576,-470.66966 490.44062,-460.60293 474.43859,-443.91718 C 464.25548,-432.30843 456.98183,-417.57202 456.98183,-401.2354 C 456.98183,-378.75982 465.71021,-362.81598 481.71224,-350.11619 C 497.71427,-339.42392 515.17103,-332.45577 532.62779,-327.34966 C 552.99401,-321.05068 568.99604,-315.59544 568.99604,-303.89942 C 568.99604,-299.57887 567.54131,-295.6511 564.63185,-292.49433 C 558.81293,-287.27185 551.53928,-285.29342 539.90144,-285.04611 C 519.53522,-284.66789 504.98792,-287.91193 480.25751,-302.3574 L 456.98183,-257.47898 C 481.71224,-243.57176 510.80684,-235.39618 539.90144,-235.39618 L 544.26563,-235.42527 C 568.99604,-235.89079 590.81699,-243.23717 606.81902,-256.5916 C 608.27375,-257.37715 608.27375,-258.10452 609.72848,-258.83188 L 602.45483,-239.29486 L 669.37241,-239.29486 L 679.55552,-273.16097 C 691.19336,-269.26229 704.28593,-266.99292 718.83323,-266.99292 C 733.38053,-266.99292 745.01837,-269.18956 756.65621,-272.88457 L 768.29405,-239.29486 L 875.94407,-239.29486 L 875.94407,-309.54377 L 900.67448,-309.54377 C 957.40895,-309.54377 990.86774,-338.65292 990.86774,-387.47365 C 990.86774,-441.82237 958.86368,-466.77099 887.58191,-466.77099 z M 718.83323,-317.79209 C 710.10485,-317.79209 702.8312,-319.30501 695.55755,-321.95261 L 718.83323,-395.15463 L 718.83323,-395.15463 L 742.10891,-321.71986 C 734.83526,-319.21772 727.56161,-317.79209 718.83323,-317.79209 z M 891.9461,-359.89197 L 875.94407,-359.89197 L 875.94407,-418.91037 L 891.9461,-418.91037 C 913.76705,-418.91037 931.22381,-411.76765 931.22381,-389.69939 C 931.22381,-367.0056 913.76705,-359.89197 891.9461,-359.89197" style="fill:#FFF;fill-rule:evenodd;stroke:none"/>
|
||||
<path d="M 913.76705,-191.53607 C 913.76705,-202.78113 922.49543,-211.34949 932.67854,-211.34949 C 942.86165,-211.34949 951.59003,-202.78113 951.59003,-191.53607 C 951.59003,-179.86914 942.86165,-171.4608 932.67854,-171.4608 C 922.49543,-171.4608 913.76705,-179.86914 913.76705,-191.53607 z M 932.67854,-167.47484 C 945.77111,-167.47484 957.40895,-177.67249 957.40895,-191.53607 C 957.40895,-205.19599 945.77111,-215.23362 932.67854,-215.23362 C 919.58597,-215.23362 907.94813,-205.19599 907.94813,-191.53607 C 907.94813,-177.67249 919.58597,-167.47484 932.67854,-167.47484 z M 928.31435,-189.54309 L 932.67854,-189.54309 L 939.95219,-177.67249 L 944.31638,-177.67249 L 937.04273,-189.77585 C 939.95219,-190.27046 944.31638,-192.40891 944.31638,-197.2968 C 944.31638,-202.78113 939.95219,-205.19599 934.13327,-205.19599 L 923.95016,-205.19599 L 923.95016,-177.67249 L 928.31435,-177.67249 L 928.31435,-189.54309 z M 928.31435,-193.09263 L 928.31435,-201.69009 L 934.13327,-201.69009 C 935.588,-201.69009 939.95219,-201.02091 939.95219,-197.54411 C 939.95219,-193.36903 935.588,-193.09263 932.67854,-193.09263 L 928.31435,-193.09263" style="fill:#014185;fill-rule:nonzero;stroke:none"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="9" cy="7" r="4"></circle>
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87"></path>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 435 B |
@@ -0,0 +1,10 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect>
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||||
stroke="rgb(37 99 235 / var(--tw-text-opacity, 1))"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 699 B |
@@ -0,0 +1 @@
|
||||
dummy image content
|
||||
@@ -0,0 +1 @@
|
||||
document.getElementById('contact-form').addEventListener('submit', function(event) { event.preventDefault(); const formData = new FormData(event.target); fetch(event.target.action, { method: event.target.method, body: formData, }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log('Success:', data); }) .catch((error) => { console.error('Error:', error); }); });
|
||||
@@ -0,0 +1 @@
|
||||
function HumansNotBots(replacement_method, strAT, strDOT) { if (document.getElementsByTagName) { if (strAT == null || strDOT == null) { strAT = "AT"; strDOT = "DOT"; } var disguisedForm = "([a-zA-Z0-9._%+-]+)\\s" + strAT + "\\s([a-zA-Z0-9.-]+)\\s" + strDOT + "\\s(co.uk|[a-zA-Z]{2,4})"; var htmlbody = document.getElementsByTagName("body")[0]; if (replacement_method == "innerhtml") HumansNotBots_innerhtml(htmlbody, disguisedForm); else if (replacement_method == "dom") HumansNotBots_dom(htmlbody, disguisedForm); } } function HumansNotBots_innerhtml(htmlbody, disguisedForm) { var matchexp = new RegExp(disguisedForm, "g"); var replacement = '<a href="mailto:$1@$2.$3">$1@$2.$3</a>'; var newInnerHTML = htmlbody.innerHTML.replace(matchexp, replacement); htmlbody.innerHTML = newInnerHTML; } function HumansNotBots_dom(element, disguisedForm) { if (element) { if (element.hasChildNodes()) { var child = element.firstChild; while (child) { HumansNotBots_dom(child, disguisedForm); child = child.nextSibling; } } else if (element.nodeValue) { var matchexp = new RegExp(disguisedForm, "g"); var disguisedEmailAddresses = element.nodeValue.match(matchexp); if (disguisedEmailAddresses !== null) { var unprocessedText = element.nodeValue; var newParentsChildren = new Array(); for (var i = 0; i < disguisedEmailAddresses.length; i++) { var disguisedEmailAddress = disguisedEmailAddresses[i]; var textBefore = unprocessedText.substring( 0, unprocessedText.search(new RegExp(disguisedEmailAddress)) ); if (textBefore) { newParentsChildren.push(document.createTextNode(textBefore)); } var matchexp1 = new RegExp(disguisedForm); var realEmailAddress = disguisedEmailAddress.replace( matchexp1, "$1@$2.$3" ); var a = document.createElement("a"); a.setAttribute("href", "mailto:" + realEmailAddress); a.appendChild(document.createTextNode(realEmailAddress)); newParentsChildren.push(a); unprocessedText = unprocessedText.substring( textBefore.length + disguisedEmailAddress.length ); } if (unprocessedText) { newParentsChildren.push(document.createTextNode(unprocessedText)); } var parent = element.parentNode; var child = newParentsChildren.shift(); while (child) { parent.insertBefore(child, element); child = newParentsChildren.shift(); } parent.removeChild(element); } } } }
|
||||
@@ -0,0 +1 @@
|
||||
document.addEventListener("DOMContentLoaded", function () { const hamburger = document.querySelector(".hamburger-menu"); const navMenu = document.querySelector(".nav-menu"); if (!hamburger || !navMenu) { return; } hamburger.addEventListener("click", function () { hamburger.classList.toggle("open"); navMenu.classList.toggle("open"); }); document.addEventListener("click", function (event) { if (!hamburger.contains(event.target) && !navMenu.contains(event.target)) { hamburger.classList.remove("open"); navMenu.classList.remove("open"); } }); navMenu.addEventListener("click", function (event) { if (event.target.tagName === "A") { hamburger.classList.remove("open"); navMenu.classList.remove("open"); } }); });
|
||||
@@ -0,0 +1 @@
|
||||
function partnerRotate(interval = 3000) { const partners = document.querySelectorAll("img[src*='img/partner/']"); for (let i = 1; i < partners.length; i++) { partners[i].classList.add("hidden"); } let currentIndex = 0; const totalPartners = partners.length; setInterval(() => { partners[currentIndex].classList.add("hidden"); currentIndex = (currentIndex + 1) % totalPartners; partners[currentIndex].classList.remove("hidden"); }, interval); } window.onload = function () { partnerRotate(5000); };
|
||||
@@ -0,0 +1,20 @@
|
||||
; cPanel-generated php ini directives, do not edit
|
||||
; Manual editing of this file may result in unexpected behavior.
|
||||
; To make changes to this file, use the cPanel MultiPHP INI Editor (Home >> Software >> MultiPHP INI Editor)
|
||||
; For more information, read our documentation (https://go.cpanel.net/EA4ModifyINI)
|
||||
|
||||
allow_url_fopen = On
|
||||
allow_url_include = Off
|
||||
asp_tags = Off
|
||||
display_errors = Off
|
||||
enable_dl = Off
|
||||
file_uploads = On
|
||||
max_execution_time = 30
|
||||
max_input_time = 60
|
||||
max_input_vars = 1000
|
||||
memory_limit = 64M
|
||||
post_max_size = 16M
|
||||
session.gc_maxlifetime = 1440
|
||||
session.save_path = "/var/cpanel/php/sessions/ea-php56"
|
||||
upload_max_filesize = 16M
|
||||
zlib.output_compression = Off
|
||||
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -0,0 +1,122 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="https://allucanget.biz/css/styles.css" />
|
||||
<title>Email Signature - AllYouCanGET</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
line-height: 1.4;
|
||||
color: #333333;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.signature-container {
|
||||
max-width: 600px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.logo-section {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 60px;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #101828;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.position {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
margin-bottom: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.contact-details {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.contact-link {
|
||||
color: #0a0a0a;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.contact-link:hover {
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.address {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #e5e7eb;
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.address-line {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="signature-container">
|
||||
<div class="logo-section">
|
||||
<img src="https://allucanget.biz/img/Logo-AllYouCanGet-204x100.png" alt="AllYouCanGET" class="logo" />
|
||||
</div>
|
||||
<div class="contact-info">
|
||||
<div class="name">Georg Sinn</div>
|
||||
<div class="position">IT & Management Consulting</div>
|
||||
<div class="contact-details">
|
||||
<div class="contact-item">
|
||||
<a href="tel:+41799236402" class="contact-link">+41-79-9236402</a>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<a href="mailto:georg@allucanget.biz" class="contact-link">georg@allucanget.biz</a>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<a href="https://allucanget.biz" class="contact-link">allucanget.biz</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="address">
|
||||
<div class="address-line">All You Can GET</div>
|
||||
<div class="address-line">c/o Sinn Consulting</div>
|
||||
<div class="address-line">Im Dornäcker 16</div>
|
||||
<div class="address-line">8967 Widen</div>
|
||||
<div class="address-line">Switzerland</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,398 @@
|
||||
"""
|
||||
Markdown parser for converting Markdown files into structured component data.
|
||||
|
||||
This module reads Markdown files and returns a structured representation that maps
|
||||
heading levels to component types:
|
||||
- H1 (#) -> page title / hero
|
||||
- H2 (##) -> major sections
|
||||
- H3 (###) -> cards or subsections within sections
|
||||
- Lists -> converted to component-compatible format
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import textwrap
|
||||
import markdown
|
||||
from bs4 import BeautifulSoup
|
||||
from markdown.treeprocessors import Treeprocessor
|
||||
from markdown.preprocessors import Preprocessor
|
||||
from markdown.extensions import Extension
|
||||
from typing import Dict, List, Any, Optional, cast
|
||||
from lib.types import PageData, Section, Card, Detail, ParserState
|
||||
|
||||
|
||||
class HeadingCollector(Treeprocessor):
|
||||
"""
|
||||
Custom Markdown tree processor that collects headings and their content.
|
||||
"""
|
||||
|
||||
def __init__(self, md: Any) -> None:
|
||||
super().__init__(md)
|
||||
self.headings: List[Dict[str, Any]] = []
|
||||
self.current_content: List[str] = []
|
||||
self.main_intro: str = ''
|
||||
|
||||
def run(self, root: Any) -> Any:
|
||||
"""Process the element tree and collect headings with content."""
|
||||
self.headings = []
|
||||
self.main_intro = ''
|
||||
collecting_intro = False
|
||||
for element in root:
|
||||
if element.tag == 'h1':
|
||||
collecting_intro = True
|
||||
elif collecting_intro and element.tag in ['h2', 'h3', 'h4', 'h5', 'h6']:
|
||||
collecting_intro = False
|
||||
elif collecting_intro:
|
||||
intro_text = self._extract_text(element)
|
||||
if intro_text:
|
||||
if self.main_intro:
|
||||
self.main_intro += '\n\n' + intro_text
|
||||
else:
|
||||
self.main_intro = intro_text
|
||||
self._process_element(element)
|
||||
return root
|
||||
|
||||
def _process_element(self, element: Any) -> None:
|
||||
"""Recursively process elements to extract heading structure."""
|
||||
if element.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
|
||||
# Convert heading tag to level (e.g., 'h2' -> 2)
|
||||
level = int(element.tag[1])
|
||||
text = self._extract_text(element)
|
||||
self.headings.append({
|
||||
'level': level if level > 1 else 2, # Treat H1 as level 2 for sectioning
|
||||
'text': text,
|
||||
'tag': element.tag,
|
||||
'element': element,
|
||||
})
|
||||
elif element.tag in ['ul', 'ol']:
|
||||
# Extract list items
|
||||
items: List[str] = []
|
||||
for li in element:
|
||||
items.append(self._extract_text(li))
|
||||
self.headings.append({
|
||||
'type': element.tag,
|
||||
'items': items,
|
||||
'element': element,
|
||||
})
|
||||
else:
|
||||
# Process children
|
||||
for child in element:
|
||||
self._process_element(child)
|
||||
|
||||
def _extract_text(self, element: Any) -> str:
|
||||
"""Extract all text from an element and its children."""
|
||||
if element.text:
|
||||
text = element.text
|
||||
else:
|
||||
text = ''
|
||||
for child in element:
|
||||
text += self._extract_text(child)
|
||||
if child.tail:
|
||||
text += child.tail
|
||||
return text.strip()
|
||||
|
||||
|
||||
class DedentPreprocessor(Preprocessor):
|
||||
"""Normalize leading indentation so headings aren't treated as code blocks."""
|
||||
|
||||
def run(self, lines: List[str]) -> List[str]:
|
||||
text = '\n'.join(lines)
|
||||
dedented = textwrap.dedent(text)
|
||||
return dedented.split('\n')
|
||||
|
||||
|
||||
class HeadingExtension(Extension):
|
||||
"""Markdown extension to collect headings."""
|
||||
|
||||
def extendMarkdown(self, md: Any) -> None:
|
||||
md.preprocessors.register(
|
||||
DedentPreprocessor(md), 'dedent_preprocessor', 27)
|
||||
md.treeprocessors.register(
|
||||
HeadingCollector(md), 'heading_collector', 5)
|
||||
|
||||
|
||||
def parse_markdown_file(file_path: str) -> PageData:
|
||||
"""
|
||||
Parse a Markdown file and return a structured representation.
|
||||
|
||||
Args:
|
||||
file_path (str): Path to the Markdown file to parse.
|
||||
|
||||
Returns:
|
||||
dict: A nested dictionary representing the page structure.
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If the file does not exist.
|
||||
IOError: If there is an error reading the file.
|
||||
"""
|
||||
if not os.path.exists(file_path):
|
||||
raise FileNotFoundError(f"Markdown file not found: {file_path}")
|
||||
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# Parse the content to extract structure
|
||||
return build_component_structure(content, file_path)
|
||||
|
||||
|
||||
def get_markdown_files(docs_dir: str = 'docs/en') -> List[str]:
|
||||
"""Return Markdown filenames from the given docs directory."""
|
||||
if not os.path.exists(docs_dir):
|
||||
return []
|
||||
return [f for f in os.listdir(docs_dir) if f.endswith('.md')]
|
||||
|
||||
|
||||
def markdown_filename_to_html_filename(md_filename: str) -> str:
|
||||
"""Convert a Markdown filename to its HTML counterpart."""
|
||||
return md_filename.replace('.md', '.html').lower()
|
||||
|
||||
|
||||
def build_component_structure(
|
||||
markdown_content: str, file_path: str) -> PageData:
|
||||
"""
|
||||
Build a nested component structure from Markdown content.
|
||||
|
||||
This function parses Markdown headings and content into a hierarchical structure
|
||||
suitable for rendering with component templates.
|
||||
"""
|
||||
lines = markdown_content.split('\n')
|
||||
page: PageData = {
|
||||
'title': None,
|
||||
'sections': [],
|
||||
}
|
||||
current_section: Optional[Section] = None
|
||||
current_card: Optional[Card] = None
|
||||
current_detail: Optional[Detail] = None
|
||||
content_buffer: List[str] = []
|
||||
detail_buffer: List[str] = []
|
||||
|
||||
# Move local state into a dict so module-level helpers can operate on it
|
||||
state: ParserState = {
|
||||
'page': page,
|
||||
'current_section': current_section,
|
||||
'current_card': current_card,
|
||||
'current_detail': current_detail,
|
||||
'content_buffer': content_buffer,
|
||||
'detail_buffer': detail_buffer,
|
||||
}
|
||||
|
||||
for line in lines:
|
||||
process_line_with_state(line, state)
|
||||
|
||||
# Rehydrate locals from state
|
||||
current_section = state['current_section']
|
||||
current_card = state['current_card']
|
||||
current_detail = state['current_detail']
|
||||
content_buffer = state['content_buffer']
|
||||
detail_buffer = state['detail_buffer']
|
||||
|
||||
# Flush remaining content
|
||||
flush_detail_buffer(state)
|
||||
# Flush content buffer to card or section as appropriate
|
||||
if current_card is not None and content_buffer:
|
||||
current_card['content'] = markdown_to_html_lines(
|
||||
'\n'.join(content_buffer).strip())
|
||||
elif current_section is not None and content_buffer:
|
||||
current_section['content'] = markdown_to_html_lines(
|
||||
'\n'.join(content_buffer).strip())
|
||||
|
||||
if page['title'] is None:
|
||||
filename = os.path.basename(file_path)
|
||||
page['title'] = os.path.splitext(filename)[0].replace('_', ' ').title()
|
||||
|
||||
return page
|
||||
|
||||
|
||||
def flush_detail_buffer(state: ParserState) -> None:
|
||||
"""Flush the detail buffer into the current detail entry."""
|
||||
current_detail = state['current_detail']
|
||||
detail_buffer = state['detail_buffer']
|
||||
if current_detail is not None and detail_buffer:
|
||||
current_detail['content'] = markdown_to_html_lines(
|
||||
'\n'.join(detail_buffer).strip())
|
||||
state['detail_buffer'] = []
|
||||
|
||||
|
||||
def flush_content_buffer_to_card(state: ParserState) -> None:
|
||||
"""Flush the content buffer into the current card."""
|
||||
current_card = state['current_card']
|
||||
content_buffer = state['content_buffer']
|
||||
if current_card is not None and content_buffer:
|
||||
current_card['content'] = markdown_to_html_lines(
|
||||
'\n'.join(content_buffer).strip())
|
||||
|
||||
|
||||
def flush_content_buffer_to_section(state: ParserState) -> None:
|
||||
"""Flush the content buffer into the current section."""
|
||||
current_section = state['current_section']
|
||||
content_buffer = state['content_buffer']
|
||||
if current_section is not None and content_buffer:
|
||||
current_section['content'] = markdown_to_html_lines(
|
||||
'\n'.join(content_buffer).strip())
|
||||
|
||||
|
||||
def start_section(title: str, state: ParserState) -> None:
|
||||
"""Start a new section with the given title."""
|
||||
if state['current_card'] is not None:
|
||||
flush_content_buffer_to_card(state)
|
||||
state['content_buffer'] = []
|
||||
state['current_card'] = None
|
||||
if state['current_section'] is not None:
|
||||
flush_content_buffer_to_section(state)
|
||||
section = cast(Section, {
|
||||
'title': title,
|
||||
'content': '',
|
||||
'cards': []
|
||||
})
|
||||
sections = state['page'].get('sections', [])
|
||||
sections.append(section)
|
||||
state['page']['sections'] = sections
|
||||
state['current_section'] = section
|
||||
state['content_buffer'] = []
|
||||
state['current_card'] = None
|
||||
|
||||
|
||||
def start_card(title: str, state: ParserState) -> None:
|
||||
"""Start a new card within the current section."""
|
||||
if state['current_section'] is None:
|
||||
return
|
||||
if state['current_card'] is None:
|
||||
flush_content_buffer_to_section(state)
|
||||
else:
|
||||
flush_content_buffer_to_card(state)
|
||||
card = cast(Card, {
|
||||
'title': title,
|
||||
'content': ''
|
||||
})
|
||||
state['current_section']['cards'].append(card)
|
||||
state['current_card'] = card
|
||||
state['content_buffer'] = []
|
||||
|
||||
|
||||
def start_detail(title: str, state: ParserState) -> None:
|
||||
"""Start a new detail within the current card."""
|
||||
if state['current_card'] is None:
|
||||
return
|
||||
if state['current_detail'] is not None and state['detail_buffer']:
|
||||
state['current_detail']['content'] = markdown_to_html_lines(
|
||||
'\n'.join(state['detail_buffer']).strip())
|
||||
state['detail_buffer'] = []
|
||||
detail = cast(Detail, {
|
||||
'title': title,
|
||||
'content': ''
|
||||
})
|
||||
if 'details' not in state['current_card']:
|
||||
state['current_card']['details'] = []
|
||||
state['current_card']['details'].append(detail)
|
||||
state['current_detail'] = detail
|
||||
|
||||
|
||||
def process_line_with_state(line: str, state: ParserState) -> None:
|
||||
"""Process a single markdown line, updating the provided state dict."""
|
||||
if line.startswith('# '):
|
||||
# H1 - page title
|
||||
state['page']['title'] = line[2:].strip()
|
||||
# intro content before sections
|
||||
if state['current_section'] is not None and state['content_buffer']:
|
||||
flush_content_buffer_to_section(state)
|
||||
state['current_section'] = None
|
||||
elif line.startswith('## '):
|
||||
# H2 - major section
|
||||
flush_detail_buffer(state)
|
||||
title = line[3:].strip()
|
||||
title = check_image_in_title(title)
|
||||
start_section(title, state)
|
||||
elif line.startswith('### '):
|
||||
# H3 - card or subsection
|
||||
flush_detail_buffer(state)
|
||||
title = line[4:].strip()
|
||||
title = check_image_in_title(title)
|
||||
start_card(title, state)
|
||||
elif line.startswith('#### '):
|
||||
# H4 - detail inside a card
|
||||
if state['current_card'] is not None:
|
||||
title = line[5:].strip()
|
||||
title = check_image_in_title(title)
|
||||
start_detail(title, state)
|
||||
else:
|
||||
state['content_buffer'].append(line)
|
||||
elif line.strip():
|
||||
if state['current_detail'] is not None:
|
||||
state['detail_buffer'].append(line)
|
||||
else:
|
||||
state['content_buffer'].append(line)
|
||||
|
||||
|
||||
def check_image_in_title(title: str) -> str:
|
||||
"""
|
||||
Check if there is an image in the title, preserve original title text and create HTML img tag with alt text and src.
|
||||
"""
|
||||
img_pattern = r'!\[([^\]]*)\]\(([^)]+)\)'
|
||||
match = re.search(img_pattern, title)
|
||||
if match:
|
||||
alt_text = match.group(1).strip()
|
||||
src = match.group(2).strip()
|
||||
img_tag = f'<img src="{src}" alt="{alt_text}"/>'
|
||||
title = re.sub(img_pattern, img_tag, title).strip()
|
||||
return title
|
||||
|
||||
|
||||
def markdown_to_html_lines(text: str) -> str:
|
||||
"""
|
||||
Convert Markdown text to HTML.
|
||||
"""
|
||||
if not text:
|
||||
return ''
|
||||
|
||||
md = markdown.Markdown()
|
||||
html = md.convert(text)
|
||||
|
||||
def _is_unsafe(href: str) -> bool:
|
||||
lower = href.strip().lower()
|
||||
return lower.startswith('javascript:') or lower.startswith(
|
||||
'data:') or lower.startswith('vbscript:')
|
||||
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
for anchor in soup.find_all('a'):
|
||||
href = anchor.get('href')
|
||||
if isinstance(href, (list, tuple)):
|
||||
href = href[0]
|
||||
href = (href or '').strip()
|
||||
if not href:
|
||||
continue
|
||||
if _is_unsafe(href):
|
||||
anchor['href'] = '#unsafe'
|
||||
anchor.attrs.pop('target', None)
|
||||
anchor.attrs.pop('rel', None)
|
||||
continue
|
||||
if href.startswith('http://') or href.startswith('https://'):
|
||||
anchor['target'] = '_blank'
|
||||
anchor['rel'] = 'noopener noreferrer'
|
||||
|
||||
for image in soup.find_all('img'):
|
||||
src = image.get('src') or ''
|
||||
if isinstance(src, (list, tuple)):
|
||||
src = src[0]
|
||||
src = src.strip()
|
||||
if not src:
|
||||
image.decompose()
|
||||
continue
|
||||
|
||||
alt = image.get('alt')
|
||||
if isinstance(alt, (list, tuple)):
|
||||
alt = alt[0]
|
||||
alt_text = (alt or '').strip()
|
||||
# Determine final src for relative paths
|
||||
if not (src.startswith('http://') or src.startswith('https://')
|
||||
or src.startswith('/') or src.startswith('img/')):
|
||||
filename = os.path.basename(src)
|
||||
src = f'img/{filename}' if filename else src
|
||||
image['src'] = src
|
||||
|
||||
if not alt_text:
|
||||
alt_text = os.path.splitext(os.path.basename(src))[
|
||||
0].replace('-', ' ').replace('_', ' ').strip()
|
||||
image['alt'] = alt_text
|
||||
|
||||
return str(soup)
|
||||
@@ -0,0 +1,54 @@
|
||||
from typing import TypedDict, List, Dict, Optional
|
||||
|
||||
|
||||
class Detail(TypedDict):
|
||||
title: str
|
||||
content: str
|
||||
|
||||
|
||||
class Card(TypedDict, total=False):
|
||||
title: str
|
||||
content: str
|
||||
details: List[Detail]
|
||||
|
||||
|
||||
class Section(TypedDict):
|
||||
title: str
|
||||
content: str
|
||||
cards: List[Card]
|
||||
|
||||
|
||||
class PageData(TypedDict):
|
||||
title: Optional[str]
|
||||
sections: List[Section]
|
||||
|
||||
|
||||
class PageMeta(TypedDict, total=False):
|
||||
title: str
|
||||
description: str
|
||||
keywords: str
|
||||
og_description: str
|
||||
favicon: str
|
||||
twitter_image: str
|
||||
og_image: str
|
||||
|
||||
|
||||
class PageEntry(TypedDict, total=False):
|
||||
page_title: str
|
||||
page_subtitle: str
|
||||
page_cta: str
|
||||
page_cta_url: str
|
||||
meta: PageMeta
|
||||
active: bool
|
||||
|
||||
|
||||
PagesDict = Dict[str, PageEntry]
|
||||
|
||||
|
||||
class ParserState(TypedDict):
|
||||
page: PageData
|
||||
current_section: Optional[Section]
|
||||
current_card: Optional[Card]
|
||||
current_detail: Optional[Detail]
|
||||
content_buffer: List[str]
|
||||
detail_buffer: List[str]
|
||||
@@ -0,0 +1,126 @@
|
||||
import os
|
||||
import re
|
||||
from typing import Dict, List, Any
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from lib.types import PagesDict
|
||||
|
||||
DEFAULT_TEMPLATE_DIR = 'templates'
|
||||
DEFAULT_OUTPUT_DIR = 'html'
|
||||
|
||||
|
||||
def get_template_files(template_dir: str = DEFAULT_TEMPLATE_DIR) -> List[str]:
|
||||
"""Return template filenames from the provided template directory."""
|
||||
if not os.path.exists(template_dir):
|
||||
return []
|
||||
return [
|
||||
name
|
||||
for name in os.listdir(template_dir)
|
||||
if name.endswith('.html') and not name.startswith('_')
|
||||
]
|
||||
|
||||
|
||||
def get_css_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
|
||||
"""Return CSS file paths contained in the output directory's css folder."""
|
||||
css_dir = os.path.join(output_dir, 'css')
|
||||
if not os.path.exists(css_dir):
|
||||
return []
|
||||
return [
|
||||
os.path.join(css_dir, name)
|
||||
for name in os.listdir(css_dir)
|
||||
if name.endswith('.css')
|
||||
]
|
||||
|
||||
|
||||
def get_js_files(output_dir: str = DEFAULT_OUTPUT_DIR) -> List[str]:
|
||||
"""Return JavaScript file paths contained in the output directory's js folder."""
|
||||
js_dir = os.path.join(output_dir, 'js')
|
||||
if not os.path.exists(js_dir):
|
||||
return []
|
||||
return [
|
||||
os.path.join(js_dir, name)
|
||||
for name in os.listdir(js_dir)
|
||||
if name.endswith('.js')
|
||||
]
|
||||
|
||||
|
||||
def render_template(
|
||||
template_name: str,
|
||||
context: Dict[str, Any],
|
||||
template_dir: str = DEFAULT_TEMPLATE_DIR) -> str:
|
||||
"""Render a Jinja2 template with the provided context."""
|
||||
env = Environment(loader=FileSystemLoader(template_dir))
|
||||
template = env.get_template(template_name)
|
||||
return template.render(context)
|
||||
|
||||
|
||||
def set_active_page_by_url(pages: PagesDict, page_url: str) -> None:
|
||||
"""Mutate navigation dictionary to mark the active page."""
|
||||
for key, value in pages.items():
|
||||
# value is a PageEntry TypedDict
|
||||
value['active'] = key == page_url
|
||||
|
||||
|
||||
def minify_js(js: str) -> str:
|
||||
"""Minify JavaScript by removing comments and redundant whitespace."""
|
||||
js = re.sub(r'//.*?\n|/\*.*?\*/', '', js, flags=re.DOTALL)
|
||||
js = re.sub(r'\s+', ' ', js)
|
||||
js = re.sub(r';\s+', ';\n', js)
|
||||
js = re.sub(r'\n+', ' ', js)
|
||||
return js.strip()
|
||||
|
||||
|
||||
def minify_css(css: str) -> str:
|
||||
"""Minify CSS by removing comments and redundant whitespace."""
|
||||
css = re.sub(r'/\*.*?\*/', '', css, flags=re.DOTALL)
|
||||
css = re.sub(r'\s+', ' ', css)
|
||||
css = re.sub(r';\s+', ';\n', css)
|
||||
css = re.sub(r'\s+([\{\s])', r'\1', css)
|
||||
css = re.sub(r'\s+}', '}', css)
|
||||
css = re.sub(r'\n+', ' ', css)
|
||||
return css.strip()
|
||||
|
||||
|
||||
def minify_html(html: str) -> str:
|
||||
"""Minify HTML by removing comments and redundant whitespace."""
|
||||
html = re.sub(r'<!--.*?-->', '', html, flags=re.DOTALL)
|
||||
html = re.sub(r'\s+', ' ', html)
|
||||
html = re.sub(r'>\s+<', '><', html)
|
||||
html = re.sub(r'<\s+', '<', html)
|
||||
html = re.sub(r'\s+</', '</', html)
|
||||
return html.strip()
|
||||
|
||||
|
||||
def css_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
|
||||
"""Minify all CSS files within the output directory."""
|
||||
for css_path in get_css_files(output_dir):
|
||||
with open(css_path, 'r', encoding='utf-8') as handle:
|
||||
content = handle.read()
|
||||
minified = minify_css(content)
|
||||
with open(css_path, 'w', encoding='utf-8') as handle:
|
||||
handle.write(minified)
|
||||
|
||||
|
||||
def js_minifier(output_dir: str = DEFAULT_OUTPUT_DIR) -> None:
|
||||
"""Minify all JavaScript files within the output directory."""
|
||||
for js_path in get_js_files(output_dir):
|
||||
with open(js_path, 'r', encoding='utf-8') as handle:
|
||||
content = handle.read()
|
||||
minified = minify_js(content)
|
||||
with open(js_path, 'w', encoding='utf-8') as handle:
|
||||
handle.write(minified)
|
||||
|
||||
|
||||
__all__ = [
|
||||
'DEFAULT_OUTPUT_DIR',
|
||||
'DEFAULT_TEMPLATE_DIR',
|
||||
'get_template_files',
|
||||
'get_css_files',
|
||||
'get_js_files',
|
||||
'render_template',
|
||||
'set_active_page_by_url',
|
||||
'minify_js',
|
||||
'minify_css',
|
||||
'minify_html',
|
||||
'css_minifier',
|
||||
'js_minifier',
|
||||
]
|
||||
@@ -0,0 +1,189 @@
|
||||
import json
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
from lib.markdown_parser import (
|
||||
parse_markdown_file,
|
||||
get_markdown_files,
|
||||
markdown_filename_to_html_filename,
|
||||
)
|
||||
from lib.utils import (
|
||||
get_template_files,
|
||||
render_template,
|
||||
set_active_page_by_url,
|
||||
minify_html,
|
||||
js_minifier,
|
||||
)
|
||||
from lib.types import PagesDict
|
||||
|
||||
TEMPLATE_DIR = 'templates'
|
||||
OUTPUT_DIR = 'html'
|
||||
|
||||
PAGES_JSON = 'docs/pages.json'
|
||||
|
||||
# Load json data for navigation and pages if needed
|
||||
with open(PAGES_JSON, 'r') as f:
|
||||
PAGES = json.load(f)
|
||||
|
||||
|
||||
# Ensure output directory exists
|
||||
if not os.path.exists(OUTPUT_DIR):
|
||||
os.makedirs(OUTPUT_DIR)
|
||||
|
||||
|
||||
def get_pages() -> PagesDict:
|
||||
"""Load and return pages data from the pages.json file.
|
||||
|
||||
Returns:
|
||||
dict: Pages dictionary structured as follows:
|
||||
{
|
||||
"page.html": {
|
||||
"name": str,
|
||||
"url": str,
|
||||
"active": str,
|
||||
"page_title": str,
|
||||
"page_subtitle": str,
|
||||
"page_cta": str,
|
||||
"page_cta_url": str,
|
||||
"meta": {
|
||||
"title": str,
|
||||
"description": str,
|
||||
"keywords": str,
|
||||
"og_description": str,
|
||||
}
|
||||
},
|
||||
{...}
|
||||
}
|
||||
"""
|
||||
# Set a default favicon for all pages
|
||||
favicon = 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png'
|
||||
with open(PAGES_JSON, 'r', encoding='utf-8') as f:
|
||||
pages = json.load(f)
|
||||
|
||||
# Update the meta information for each page
|
||||
for page in pages.values():
|
||||
page['meta']['favicon'] = favicon
|
||||
page['meta']['og_image'] = favicon
|
||||
page['meta']['twitter_image'] = favicon
|
||||
return pages
|
||||
|
||||
|
||||
def process_markdown_file(
|
||||
md_file_path: str,
|
||||
output_html_path: str,
|
||||
pages: PagesDict,
|
||||
template_dir: str = TEMPLATE_DIR,
|
||||
):
|
||||
"""
|
||||
Process a single Markdown file and render it using the page_from_md template.
|
||||
|
||||
Args:
|
||||
md_file_path (str): Full path to the Markdown file.
|
||||
output_html_path (str): Full path to write the output HTML.
|
||||
pages (dict): Pages dictionary for context.
|
||||
"""
|
||||
try:
|
||||
# Parse the Markdown file
|
||||
page_data = parse_markdown_file(md_file_path)
|
||||
|
||||
# Get the HTML filename to determine active nav
|
||||
html_filename = os.path.basename(output_html_path)
|
||||
set_active_page_by_url(pages, html_filename)
|
||||
|
||||
# Build default meta data for the page
|
||||
default_meta: Dict[str, Any] = {
|
||||
'title': page_data.get('title', ''),
|
||||
'description': 'Explore our comprehensive services and coaching programs.',
|
||||
'keywords': 'consulting, coaching, services',
|
||||
'og_description': page_data.get('title', ''),
|
||||
'favicon': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
||||
'twitter_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
||||
'og_image': 'https://allucanget.biz/img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png',
|
||||
}
|
||||
page = pages.get(html_filename, {})
|
||||
meta = page.get('meta', default_meta)
|
||||
page_title = page.get('page_title', page_data.get('title', ''))
|
||||
page_subtitle = page.get('page_subtitle', '')
|
||||
|
||||
# Build context for rendering
|
||||
context: Dict[str, Any] = {
|
||||
'nav_pages': pages,
|
||||
'page': page_data,
|
||||
'page_title': page_title,
|
||||
'page_subtitle': page_subtitle,
|
||||
'meta': meta,
|
||||
'page_url': html_filename,
|
||||
'page_cta': page.get('page_cta', 'Get Started'),
|
||||
'page_cta_url': page.get('page_cta_url', '#contact-form'),
|
||||
}
|
||||
|
||||
# Render the template and write the output
|
||||
output = render_template(
|
||||
'page_from_md.html', context, template_dir=template_dir)
|
||||
html = minify_html(output)
|
||||
os.makedirs(os.path.dirname(output_html_path), exist_ok=True)
|
||||
with open(output_html_path, 'w', encoding='utf-8') as f:
|
||||
f.write(html)
|
||||
|
||||
print(f'Processed Markdown: {md_file_path} -> {output_html_path}')
|
||||
except Exception as e:
|
||||
print(f'Error processing Markdown file {md_file_path}: {e}')
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to render templates with navigation context."""
|
||||
# Get all pages with their details
|
||||
pages = get_pages()
|
||||
if not pages:
|
||||
print("No pages found to render.")
|
||||
return
|
||||
# Get navigation pages
|
||||
templates = get_template_files(TEMPLATE_DIR)
|
||||
if not templates:
|
||||
print("No templates found to render.")
|
||||
return
|
||||
print(f'Found {len(templates)} templates to process.')
|
||||
|
||||
# # Process each template
|
||||
# for template_name in templates:
|
||||
# # Skip templates that are not in the pages dictionary
|
||||
# if template_name not in pages:
|
||||
# print(f'Skipping template: {template_name}')
|
||||
# continue
|
||||
# print(f'Processing template: {template_name}')
|
||||
# # Set the active page based on the template name
|
||||
# set_active_page_by_url(pages, template_name)
|
||||
# page_details: PageEntry = pages[template_name]
|
||||
# context = {
|
||||
# 'nav_pages': pages,
|
||||
# 'page_title': page_details.get('page_title', ''),
|
||||
# 'page_subtitle': page_details.get('page_subtitle', ''),
|
||||
# 'page_cta': page_details.get('page_cta', ''),
|
||||
# 'page_cta_url': page_details.get('page_cta_url', ''),
|
||||
# 'meta': page_details.get('meta', {}),
|
||||
# }
|
||||
|
||||
# output = render_template(
|
||||
# template_name, context, template_dir=TEMPLATE_DIR)
|
||||
# html = minify_html(output)
|
||||
# with open(f'{OUTPUT_DIR}/{template_name}', 'w', encoding='utf-8') as f:
|
||||
# f.write(html)
|
||||
|
||||
# Process Markdown files from docs/en/
|
||||
print("\nProcessing Markdown files...")
|
||||
markdown_files = get_markdown_files()
|
||||
for md_file in markdown_files:
|
||||
md_path = os.path.join('docs/en', md_file)
|
||||
html_filename = markdown_filename_to_html_filename(md_file)
|
||||
html_path = os.path.join(OUTPUT_DIR, html_filename)
|
||||
process_markdown_file(md_path, html_path, pages,
|
||||
template_dir=TEMPLATE_DIR)
|
||||
|
||||
# Minify all CSS and JS files in the output directory.
|
||||
print("\nMinifying CSS and JS files...")
|
||||
# css_minifier()
|
||||
js_minifier(OUTPUT_DIR)
|
||||
print("Build complete!")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,10 @@
|
||||
jinja2
|
||||
lib
|
||||
markdown
|
||||
pytest
|
||||
beautifulsoup4
|
||||
pytest
|
||||
pytest-cov
|
||||
autopep8
|
||||
mypy
|
||||
flake8
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{% include "_head.html" %}
|
||||
<body>
|
||||
{% include "_header.html" %}
|
||||
<div id="main-content">
|
||||
<div id="main">
|
||||
{% block content %}{% endblock %} {%include
|
||||
"_footer.html" %}
|
||||
</div>
|
||||
</div>
|
||||
{% block scripts %}
|
||||
<script src="js/nav.js" defer></script>
|
||||
{% endblock %}
|
||||
<script src="js/partner.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<div id="footer">
|
||||
<div class="container">
|
||||
<p>
|
||||
© 2025
|
||||
<a href="imprint.html" class="footer-link">AllYouCanGET</a>
|
||||
| All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=EDGE" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta name="description" content="{{ meta.description }}" />
|
||||
<meta name="keywords" content="{{ meta.keywords }}" />
|
||||
|
||||
<!-- SEO and Social Sharing Meta Tags -->
|
||||
<meta name="robots" content="index, follow" />
|
||||
<link rel="canonical" href="https://allucanget.biz/{{ page_url }}" />
|
||||
<meta name="theme-color" content="#111827" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://allucanget.biz/{{ page_url }}" />
|
||||
<meta property="og:title" content="{{ meta.title }}" />
|
||||
<meta property="og:description" content="{{ meta.og_description }}" />
|
||||
<meta property="og:image" content="{{ meta.favicon }}" />
|
||||
<meta property="og:site_name" content="AllYouCanGET" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:url" content="https://allucanget.biz/{{ page_url }}" />
|
||||
<meta name="twitter:title" content="{{ meta.title }}" />
|
||||
<meta name="twitter:description" content="{{ meta.description }}" />
|
||||
<meta name="twitter:image" content="{{ meta.favicon }}" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<link
|
||||
rel="icon"
|
||||
href="img/cropped-Logo-AllYouCanGet-512x512-1-180x180.png"
|
||||
type="image/x-icon"
|
||||
/>
|
||||
<title>{{ page_title }}</title>
|
||||
</head>
|
||||
@@ -0,0 +1,56 @@
|
||||
<div id="header">
|
||||
<nav id="site-navigation">
|
||||
<div id="site-navigation-container">
|
||||
<div id="site-navigation-content">
|
||||
<div id="site-navigation-bar">
|
||||
<div id="site-navigation-brand">
|
||||
<a href="index.html" class="site-home-link">
|
||||
<img src="img/Logo-AllYouCanGet-204x100.png" alt="AllYouCanGET" class="nav-logo" />
|
||||
<span class="nav-text">AllYouCanGET</span>
|
||||
</a>
|
||||
</div>
|
||||
<button class="hamburger-menu" aria-label="Toggle navigation">
|
||||
<span class="hamburger-line"></span>
|
||||
<span class="hamburger-line"></span>
|
||||
<span class="hamburger-line"></span>
|
||||
</button>
|
||||
<div class="nav-menu">
|
||||
<div id="site-nav-links">
|
||||
{% for key, page in nav_pages.items() %} {% if page.active %}
|
||||
<a href="{{ page.url }}" class="site-nav-link active"
|
||||
>{{ page.name }}</a
|
||||
>
|
||||
{% else %}
|
||||
<a href="{{ page.url }}" class="site-nav-link">{{ page.name }}</a>
|
||||
{% endif %} {% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="page-title">
|
||||
<h2 class="page-title-header">{{ page_title }}</h2>
|
||||
<h3 class="page-subtitle">{{ page_subtitle }}</h3>
|
||||
</div>
|
||||
{% if page_cta_url %}
|
||||
<div class="header-cta">
|
||||
<div class="header-cta-buttons">
|
||||
<button class="bigbutton">
|
||||
<a href="{{ page_cta_url }}">
|
||||
<span>{{ page_cta }}</span>
|
||||
<span>→</span>
|
||||
</a>
|
||||
</button>
|
||||
{% if page_cta_url == 'services.html' %}
|
||||
<button class="bigbutton">
|
||||
<a href="#contact-form">
|
||||
<span>Contact Us</span>
|
||||
<span>→</span>
|
||||
</a>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
<nav id="site-navigation">
|
||||
<div id="site-navigation-container">
|
||||
<div id="site-navigation-content">
|
||||
<div id="site-navigation-bar">
|
||||
<div id="site-navigation-brand">
|
||||
<a href="index.html" class="site-home-link">AllYouCanGET</a>
|
||||
</div>
|
||||
<div class="nav-toggle hidden md:block">
|
||||
<div id="site-nav-links">
|
||||
{% for key, page in nav_pages.items() %} {% if page.active %}
|
||||
<a href="{{ page.url }}" class="site-nav-link active"
|
||||
>{{ page.name }}</a
|
||||
>
|
||||
{% else %}
|
||||
<a href="{{ page.url }}" class="site-nav-link">{{ page.name }}</a>
|
||||
{% endif %} {% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,498 @@
|
||||
{% extends "_base.html" %} {% block content %}
|
||||
<div class="bg-gray-50 py-12">
|
||||
<div class="container mx-auto px-6">
|
||||
<h1 class="text-4xl font-bold text-center mb-4">Our Coaching Areas</h1>
|
||||
<p class="text-xl text-gray-600 text-center mb-12">
|
||||
Comprehensive coaching programs tailored to your professional and personal
|
||||
growth
|
||||
</p>
|
||||
|
||||
<!-- Career Advice Section -->
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/coaching-career.svg"
|
||||
alt="Career advice icon"
|
||||
class="w-8 h-8 mr-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Career Advice</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Navigate your career path with expert guidance tailored to your industry
|
||||
and location.
|
||||
</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">IT Career</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Career paths in software development</li>
|
||||
<li>• Technical vs management track</li>
|
||||
<li>• Transitioning between specialties</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Switzerland Specifics</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Work culture and expectations</li>
|
||||
<li>• Salary negotiations</li>
|
||||
<li>• Work permits and regulations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Germany Specifics</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Job market trends</li>
|
||||
<li>• Industry hubs and opportunities</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Remote Work</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Building a remote work routine</li>
|
||||
<li>• Communication strategies</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Freelancing</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Setting up as independent contractor</li>
|
||||
<li>• Client acquisition and retention</li>
|
||||
<li>• Pricing strategies and negotiation</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Startups</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Evaluating startup opportunities</li>
|
||||
<li>• Equity considerations</li>
|
||||
<li>• Growth expectations</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Corporates</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Navigating corporate structures</li>
|
||||
<li>• Internal mobility</li>
|
||||
<li>• Building influence</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Consulting</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Types of consulting roles</li>
|
||||
<li>• Client management</li>
|
||||
<li>• Balancing multiple projects</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Personal Development Section -->
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/coaching-personal.svg"
|
||||
alt="Personal development icon"
|
||||
class="w-8 h-8 mr-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Personal Development</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Discover your values, strengths, and purpose to create a fulfilling life
|
||||
and career.
|
||||
</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Values</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Value identification exercises</li>
|
||||
<li>• Aligning career with personal values</li>
|
||||
<li>• Identity Workshop</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Ikigai</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Finding purpose through passion</li>
|
||||
<li>• Mission, vocation, and profession</li>
|
||||
<li>• Practical discovery exercises</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Strengths</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Assessment tools and frameworks</li>
|
||||
<li>• Leveraging strengths professionally</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Weaknesses</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Growth mindset approaches</li>
|
||||
<li>• Strategic improvement planning</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Vision</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Creating personal vision statements</li>
|
||||
<li>• Long-term life planning</li>
|
||||
<li>• Visualization techniques</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Goals</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• SMART goal framework</li>
|
||||
<li>• Balancing short and long-term objectives</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Agile Self Organization</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Personal Kanban implementation</li>
|
||||
<li>• Quarterly planning and review cycles</li>
|
||||
<li>• Agile methods for personal productivity</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Leadership Coaching Section -->
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/coaching-leadership.svg"
|
||||
alt="Leadership coaching icon"
|
||||
class="w-8 h-8 mr-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Leadership Coaching</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Develop essential leadership skills to inspire teams and drive
|
||||
organizational success.
|
||||
</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Leadership Styles</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Management vs Leadership</li>
|
||||
<li>• Situational leadership approaches</li>
|
||||
<li>• Transformational vs transactional</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Communication</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Active listening techniques</li>
|
||||
<li>• Delivering difficult messages</li>
|
||||
<li>• Cross-cultural communication</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Feedback</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Structured feedback frameworks</li>
|
||||
<li>• Creating feedback culture</li>
|
||||
<li>• Growth-oriented approaches</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Delegation</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• RACI and DACI models</li>
|
||||
<li>• Identifying tasks to delegate</li>
|
||||
<li>• Building team capacity</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Decision Making</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• OODA loop, DECIDE model</li>
|
||||
<li>• Data-driven decisions</li>
|
||||
<li>• Managing decision paralysis</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Conflict Management</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Conflict resolution models</li>
|
||||
<li>• Mediation techniques</li>
|
||||
<li>• Transforming conflict to opportunity</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Motivation</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Intrinsic vs extrinsic motivation</li>
|
||||
<li>• SCARF and Drive frameworks</li>
|
||||
<li>• Tailoring to individual needs</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Empathy & Compassion</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Building empathetic leadership</li>
|
||||
<li>• Compassion without compromising</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Trust</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Trust-building exercises</li>
|
||||
<li>• Trust in remote teams</li>
|
||||
<li>• Rebuilding broken trust</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Psychological Safety</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Assessment techniques</li>
|
||||
<li>• Creating safety in teams</li>
|
||||
<li>• Connection to innovation</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Team Building</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Tuckman's team formation</li>
|
||||
<li>• Remote team activities</li>
|
||||
<li>• Cross-functional dynamics</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h3 class="text-xl font-bold mb-3">Agile Project Management</h3>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Project roles and responsibilities</li>
|
||||
<li>• Agile hierarchies</li>
|
||||
<li>• Balancing agility with governance</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Technical Coaching Section -->
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/coaching-technical.svg"
|
||||
alt="Technical coaching icon"
|
||||
class="w-8 h-8 mr-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Technical Coaching</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Master technical skills and best practices in software development and
|
||||
IT infrastructure.
|
||||
</p>
|
||||
|
||||
<!-- Software and Web Development Subsection -->
|
||||
<h3 class="text-2xl font-bold mb-6 text-gray-700">
|
||||
Software and Web Development
|
||||
</h3>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Scalability</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Horizontal vs vertical scaling</li>
|
||||
<li>• Distributed systems principles</li>
|
||||
<li>• Load balancing strategies</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Browser</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Developer tools mastery</li>
|
||||
<li>• Performance optimization</li>
|
||||
<li>• Extension development</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Operating Systems Subsection -->
|
||||
<h3 class="text-2xl font-bold mb-6 text-gray-700">Operating Systems</h3>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Linux</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Debian, Ubuntu</li>
|
||||
<li>• RedHat, Fedora, CentOS</li>
|
||||
<li>• Arch, Manjaro</li>
|
||||
<li>• SUSE, openSUSE</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Windows</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Windows 10 & 11</li>
|
||||
<li>• Windows Server 2019</li>
|
||||
<li>• Windows Server 2022</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">macOS</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• macOS basics</li>
|
||||
<li>• System administration</li>
|
||||
<li>• Shell commands</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tools Subsection -->
|
||||
<h3 class="text-2xl font-bold mb-6 text-gray-700">Development Tools</h3>
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Git</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Advanced git workflows</li>
|
||||
<li>• Git hooks and automation</li>
|
||||
<li>• Collaboration strategies</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Docker</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Container optimization</li>
|
||||
<li>• Docker Compose</li>
|
||||
<li>• Kubernetes orchestration</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<h4 class="text-xl font-bold mb-3">Visual Studio Code</h4>
|
||||
<ul class="text-gray-600 space-y-2">
|
||||
<li>• Extension ecosystem</li>
|
||||
<li>• Customization and settings</li>
|
||||
<li>• Productivity optimization</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
<div class="bg-blue-600 text-white py-12">
|
||||
<div class="container mx-auto px-6 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4">Ready to Accelerate Your Growth?</h2>
|
||||
<p class="text-xl mb-6">
|
||||
Let's work together to unlock your full potential
|
||||
</p>
|
||||
<button
|
||||
class="bg-white text-blue-600 font-bold py-3 px-8 rounded-lg hover:bg-gray-100"
|
||||
>
|
||||
<a href="mailto:info@allucanget.biz">Schedule Your First Session</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,17 @@
|
||||
<div class="section-card">
|
||||
<h3 class="section-card-title">{{ card.title }}</h3>
|
||||
{% if card.content %}
|
||||
<div class="section-content">{{ card.content | safe }}</div>
|
||||
{% endif %} {% if card.details %}
|
||||
<div class="mt-4 space-y-3">
|
||||
{% for detail in card.details %}
|
||||
<div class="section-card-detail">
|
||||
<h4 class="section-card-detail-title">{{ detail.title }}</h4>
|
||||
{% if detail.content %}
|
||||
<div class="section-card-detail-content">{{ detail.content | safe }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,8 @@
|
||||
<div id="hero">
|
||||
<div class="container">
|
||||
<h1>{{ page.title }}</h1>
|
||||
{% if page.subtitle %}
|
||||
<p>{{ page.subtitle }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,13 @@
|
||||
<div class="section">
|
||||
<div class="section-container container">
|
||||
<h2>{{ section.title }}</h2>
|
||||
{% if section.content %}
|
||||
<div class="section-content">{{ section.content | safe }}</div>
|
||||
{% endif %} {% if section.cards %}
|
||||
<div class="section-cards">
|
||||
{% for card in section.cards %} {% include 'components/card.html' %} {%
|
||||
endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,238 @@
|
||||
{% extends "_base.html" %}{% block content %}
|
||||
<div class="bg-gray-50 py-12">
|
||||
<div class="container mx-auto px-4">
|
||||
<h1 class="text-4xl font-bold text-center mb-4">Imprint</h1>
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/imprint-shield.svg"
|
||||
alt="Shield icon"
|
||||
class="w-8 h-8 mr-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">AllYouCanGET - Sinn Consulting</h2>
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Impressum</h2>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
gemäß §5 Telemediengesetz bzw. § 5 Abs. 1 E-Commerce-Gesetz bzw. Art. 3
|
||||
des Bundesgesetzes gegen den unlauteren Wettbewerb (UWG)
|
||||
</p>
|
||||
<div
|
||||
class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex"
|
||||
>
|
||||
<div
|
||||
class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"
|
||||
>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
All You Can GET<br />c/o Sinn Consulting<br />Im Dornäcker
|
||||
16<br />CH-8967 Widen<br />georg AT allucanget DOT biz
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="mb-3" />
|
||||
<h3 class="text-xl font-bold mb-3"><strong>Overview</strong></h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
The following are the terms of an agreement between you and
|
||||
AllYouCanGET. By accessing, or using this Web site, you acknowledge that
|
||||
you have read, understand, and agree to be bound by these terms and to
|
||||
comply with all applicable laws and regulations, including export and
|
||||
re-export control laws and regulations. If you do not agree to these
|
||||
terms, please do not use this Web site.
|
||||
</p>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
AllYouCanGET may, without notice to you, at any time, revise these Terms
|
||||
of Use and any other information contained in this Web site.
|
||||
AllYouCanGET may also make improvements or changes in the products,
|
||||
services, or programs described in this site at any time without notice.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3"><strong>General</strong></h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
This Web site contains proprietary notices and copyright information,
|
||||
the terms of which must be observed and followed. Please see the tab
|
||||
entitled “Copyright and trademark information” for related information.
|
||||
</p>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
AllYouCanGET grants you a non-exclusive, non-transferable, limited
|
||||
permission to access and display the Web pages within this site as a
|
||||
customer or potential customer of AllYouCanGET provided you comply with
|
||||
these Terms of Use, and all copyright, trademark, and other proprietary
|
||||
notices remain intact. You may only use a crawler to crawl this Web site
|
||||
as permitted by this Web site’s robots.txt protocol, and AllYouCanGET
|
||||
may block any crawlers in its sole discretion. The use authorized under
|
||||
this agreement is non-commercial in nature (e.g., you may not sell the
|
||||
content you access on or through this Web site.) All other use of this
|
||||
site is prohibited.
|
||||
</p>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Except for the limited permission in the preceding paragraph,
|
||||
AllYouCanGET does not grant you any express or implied rights or
|
||||
licenses under any patents, trademarks, copyrights, or other proprietary
|
||||
or intellectual property rights. You may not mirror any of the content
|
||||
from this site on another Web site or in any other media. Any software
|
||||
and other materials that are made available for downloading, access, or
|
||||
other use from this site with their own license terms will be governed
|
||||
by such terms, conditions, and notices. Your failure to comply with such
|
||||
terms or any of the terms on this site will result in automatic
|
||||
termination of any rights granted to you, without prior notice, and you
|
||||
must immediately destroy all copies of downloaded materials in your
|
||||
possession, custody or control.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3"><strong>Disclaimer</strong></h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
From time to time, this Web site may contain technical inaccuracies or
|
||||
typographical errors, and we do not warrant the accuracy of any posted
|
||||
information. Please confirm you are using the most up-to-date pages on
|
||||
this Web site, and confirm the accuracy and completeness of information
|
||||
before using it to make decisions relating to services, products, or
|
||||
other matters described in this Web site.
|
||||
</p>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
If any term in this Terms of Use is found by competent judicial
|
||||
authority to be unenforceable in any respect, the validity of the
|
||||
remainder of this Terms of Use will be unaffected, provided that such
|
||||
unenforceability does not materially affect the parties’ rights under
|
||||
this Terms of Use.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>Forward-looking and cautionary statements</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Except for historical information and discussions, statements set forth
|
||||
throughout this web site may constitute forward-looking statements
|
||||
within the meaning of the Private Securities Litigation Reform Act of
|
||||
1995 or other applicable laws. These statements involve a number of
|
||||
risks, uncertainties, and other factors that could cause actual results
|
||||
to differ materially, as discussed in the company’s filings with
|
||||
the U.S. Securities and Exchange Commission. See the “SEC filings” tab
|
||||
under “Investor relations” on this Web site for copies of such filings.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>Confidential information</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
AllYouCanGET does not want to receive confidential or proprietary
|
||||
information from you through our Web site. Please note that any
|
||||
information or material sent to AllYouCanGET will be deemed NOT to be
|
||||
confidential. By sending AllYouCanGET any information or material, you
|
||||
grant AllYouCanGET an unrestricted, irrevocable license to copy,
|
||||
reproduce, publish, upload, post, transmit, distribute, publicly
|
||||
display, perform, modify, create derivative works from, and otherwise
|
||||
freely use, those materials or information. You also agree that
|
||||
AllYouCanGET is free to use any ideas, concepts, know-how, or techniques
|
||||
that you send us for any purpose. However, we will not release your name
|
||||
or otherwise publicize the fact that you submitted materials or other
|
||||
information to us unless: (a) we obtain your permission to use your
|
||||
name; or (b) we first notify you that the materials or other information
|
||||
you submit to a particular part of this site will be published or
|
||||
otherwise used with your name on it; or (c) we are required to do so by
|
||||
law. Personally-identifiable information that you submit to AllYouCanGET
|
||||
for the purpose of receiving products or services will be handled in
|
||||
accordance with our privacy policies. Please see the tab entitled
|
||||
“Privacy” for information regarding AllYouCanGET’s privacy policies.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>U.S. government restricted rights</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
AllYouCanGET provides the software downloaded from this Web site to U.S.
|
||||
Government users with “RESTRICTED RIGHTS.” Use, reproduction, or
|
||||
disclosure is subject to the restrictions set forth in AllYouCanGET’s
|
||||
GSA ADP Schedule contract.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>Global availability</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Information AllYouCanGET publishes on the Internet may contain
|
||||
references or cross references to AllYouCanGET products, programs and
|
||||
services that are not announced or available in your country. Such
|
||||
references do not imply that AllYouCanGET intends to announce or make
|
||||
available such products, programs, or services in your country. Please
|
||||
consult your local AllYouCanGET business contact for information
|
||||
regarding the products, programs, and services that may be available to
|
||||
you.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>Business relationships</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
This Web site may provide links or references to non-AllYouCanGET Web
|
||||
sites and resources. AllYouCanGET makes no representations, warranties,
|
||||
or other commitments or endorsements whatsoever about any
|
||||
non-AllYouCanGET Web sites or third-party resources (including any
|
||||
Lenovo Web site) that may be referenced, accessible from, or linked to
|
||||
any AllYouCanGET site. In addition, AllYouCanGET is not a party to or
|
||||
responsible for any transactions you may enter into with third parties,
|
||||
even if you learn of such parties (or use a link to such parties) from
|
||||
an AllYouCanGET site. When you access a non-AllYouCanGET Web site, even
|
||||
one that may contain the AllYouCanGET-logo, please understand that it is
|
||||
independent from AllYouCanGET, and that AllYouCanGET does not control
|
||||
the content on that Web site. It is up to you to take precautions to
|
||||
protect yourself from viruses, worms, Trojan horses, and other
|
||||
potentially destructive programs, and to protect your information.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>Linking to this site</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
AllYouCanGET consents only to links to this Web site in which the link
|
||||
and the pages that are activated by the link do not: (a) create frames
|
||||
around any page on this Web site or use other techniques that alter in
|
||||
any way the visual presentation or appearance of any content within this
|
||||
site; (b) misrepresent your relationship with AllYouCanGET; (c) imply
|
||||
that AllYouCanGET approves or endorses you, your Web site, or your
|
||||
service or product offerings; and (d) present false or misleading
|
||||
impressions about AllYouCanGET or otherwise damage the goodwill
|
||||
associated with the AllYouCanGET name or trademarks. As a further
|
||||
condition to being permitted to link to this site, you agree that
|
||||
AllYouCanGET may at any time, in its sole discretion, terminate
|
||||
permission to link to this Web site. In such event, you agree to
|
||||
immediately remove all links to this Web site and to cease any related
|
||||
use of AllYouCanGET trademarks.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>DISCLAIMER OF WARRANTY</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
USE OF THIS SITE IS AT YOUR SOLE RISK. ALL MATERIALS, INFORMATION,
|
||||
PRODUCTS, SOFTWARE, PROGRAMS, AND SERVICES ARE PROVIDED “AS
|
||||
IS,” WITH NO WARRANTIES OR GUARANTEES WHATSOEVER. AllYouCanGET
|
||||
EXPRESSLY DISCLAIMS TO THE FULLEST EXTENT PERMITTED BY LAW ALL EXPRESS,
|
||||
IMPLIED, STATUTORY, AND OTHER WARRANTIES, GUARANTEES, OR
|
||||
REPRESENTATIONS, INCLUDING, WITHOUT LIMITATION, THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT
|
||||
OF PROPRIETARY AND INTELLECTUAL PROPERTY RIGHTS. WITHOUT LIMITATION,
|
||||
AllYouCanGET MAKES NO WARRANTY OR GUARANTEE THAT THIS WEB SITE WILL BE
|
||||
UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE.
|
||||
</p>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
YOU UNDERSTAND AND AGREE THAT IF YOU DOWNLOAD OR OTHERWISE OBTAIN
|
||||
MATERIALS, INFORMATION, PRODUCTS, SOFTWARE, PROGRAMS, OR SERVICES FROM
|
||||
THIS WEB SITE, YOU DO SO AT YOUR OWN DISCRETION AND RISK AND THAT YOU
|
||||
WILL BE SOLELY RESPONSIBLE FOR ANY DAMAGES THAT MAY RESULT, INCLUDING
|
||||
LOSS OF DATA OR DAMAGE TO YOUR COMPUTER SYSTEM. SOME JURISDICTIONS DO
|
||||
NOT ALLOW THE EXCLUSION OF WARRANTIES, SO THE ABOVE EXCLUSIONS MAY NOT
|
||||
APPLY TO YOU.
|
||||
</p>
|
||||
<h3 class="text-xl font-bold mb-3">
|
||||
<strong>LIMITATION OF LIABILITY</strong>
|
||||
</h3>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
|
||||
AllYouCanGET BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY TYPE
|
||||
WHATSOEVER RELATED TO OR ARISING FROM THIS WEB SITE OR ANY USE OF THIS
|
||||
WEB SITE, OR OF ANY SITE OR RESOURCE LINKED TO, REFERENCED, OR ACCESSED
|
||||
THROUGH THIS WEB SITE, OR FOR THE USE OR DOWNLOADING OF, OR ACCESS TO,
|
||||
ANY MATERIALS, INFORMATION, PRODUCTS, OR SERVICES, INCLUDING, WITHOUT
|
||||
LIMITATION, ANY LOST PROFITS, BUSINESS INTERRUPTION, LOST SAVINGS OR
|
||||
LOSS OF PROGRAMS OR OTHER DATA, EVEN IF AllYouCanGET IS EXPRESSLY
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. THIS EXCLUSION AND WAIVER OF
|
||||
LIABILITY APPLIES TO ALL CAUSES OF ACTION, WHETHER BASED ON CONTRACT,
|
||||
WARRANTY, TORT, OR ANY OTHER LEGAL THEORIES.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,204 @@
|
||||
{% extends "_base.html" %} {% block content %}
|
||||
<div class="bg-gray-50 py-12">
|
||||
<div class="container mx-auto px-6" id="services">
|
||||
<h2 class="text-2xl md:text-4xl font-bold text-center mb-12">
|
||||
Streamline operations, optimize performance, and drive innovation with
|
||||
AllYouCanGET
|
||||
</h2>
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<a href="services.html">
|
||||
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
|
||||
<div class="w-12 h-12 text-blue-600 mb-4">
|
||||
<img
|
||||
src="img/it-consulting.svg"
|
||||
alt="IT Consulting"
|
||||
class="lucide lucide-shield w-12 h-12 text-blue-600 mb-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3">IT Consulting</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Strategic technology solutions to drive your digital transformation
|
||||
</p>
|
||||
<ul>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">IT Strategy & Planning</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Technology Assessment</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Enterprise Architecture</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Cybersecurity</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a>
|
||||
<a href="services.html">
|
||||
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
|
||||
<div class="w-12 h-12 text-blue-600 mb-4">
|
||||
<img
|
||||
src="img/management-consulting.svg"
|
||||
alt="Management Consulting"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3">Management Consulting</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Optimize operations and accelerate business growth
|
||||
</p>
|
||||
<ul>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Strategy Development</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Process Optimization</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Change Management</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Financial Analysis</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a>
|
||||
<a href="services.html">
|
||||
<div class="bg-white p-6 rounded-lg shadow-lg service-card">
|
||||
<div class="w-12 h-12 text-blue-600 mb-4">
|
||||
<img
|
||||
src="img/infrastructure.svg"
|
||||
alt="Infrastructure Services"
|
||||
class="lucide lucide-server w-12 h-12 text-blue-600 mb-4"
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold mb-3">Infrastructure Services</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Build robust foundations for your business success
|
||||
</p>
|
||||
<ul>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Cloud Solutions</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Network Design</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">System Integration</span>
|
||||
</li>
|
||||
<li class="flex items-center mb-2">
|
||||
<span class="text-green-500 mr-2">✓</span>
|
||||
<span class="text-gray-700">Security Implementation</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 py-16">
|
||||
<div class="container mx-auto px-6" id="partner">
|
||||
<h2 class="text-3xl font-bold mb-4">Our Partners</h2>
|
||||
<div class="items-center justify-center">
|
||||
<p class="text-xl mb-8">
|
||||
We collaborate with leading technology providers to deliver the best
|
||||
solutions for your business.
|
||||
</p>
|
||||
<div class="flex items-center justify-center" id="partner-logos">
|
||||
<img
|
||||
src="img/ibm.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="IBM"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/microsoft.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Microsoft"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/aws.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="AWS"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/google.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Google"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/oracle.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Oracle"
|
||||
class="h-16 w-32"
|
||||
/>
|
||||
<img
|
||||
src="img/informatica.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Informatica"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/sap.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="SAP"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
<img
|
||||
src="img/salesforce.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Salesforce"
|
||||
class="h-16 w-auto"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white py-16">
|
||||
<div class="container mx-auto px-6 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4">Ready to Transform Your Business?</h2>
|
||||
<p class="text-xl mb-8">Schedule a free consultation with our experts</p>
|
||||
<button class="bigbutton">
|
||||
<a href="mailto:info@allucanget.biz">Contact Us</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %} {% block scripts %}
|
||||
<script src="js/partner.js"></script>
|
||||
<script>
|
||||
document
|
||||
.getElementByClass("service-card")
|
||||
.addEventListener("click", function (e) {
|
||||
window.location.href = "services.html";
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,20 @@
|
||||
{% extends "_base.html" %} {% block content %}
|
||||
<!-- Hero Section with Page Title -->
|
||||
{% include 'components/hero.html' %}
|
||||
|
||||
<!-- Sections with Cards -->
|
||||
{% for section in page.sections %} {% include 'components/section.html' %} {%
|
||||
endfor %}
|
||||
|
||||
<!-- Call to Action -->
|
||||
<div id="call-to-action" class="bg-blue-600 text-white py-12">
|
||||
<div id="cta-container" class="container">
|
||||
<h2>Ready to Get Started?</h2>
|
||||
<p>
|
||||
Contact us today to learn more about how we can help you.
|
||||
</p>
|
||||
<iframe id="contact-form" src="http://contact.allucanget.biz/embed/contact" width="600" height="600" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/contact.js"></script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,208 @@
|
||||
{% extends "_base.html" %} {% block content %}
|
||||
<div class="bg-gray-50 py-12">
|
||||
<div class="container mx-auto px-6">
|
||||
<h1 class="text-4xl font-bold text-center mb-4">Our Services</h1>
|
||||
<p class="text-xl text-gray-600 text-center mb-12">
|
||||
Comprehensive solutions to transform your business
|
||||
</p>
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/it-consulting.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="IT Consulting"
|
||||
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">IT Consulting</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Comprehensive IT solutions to drive digital transformation and optimize
|
||||
your technology infrastructure.
|
||||
</p>
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/management-consulting.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="IT Strategy & Planning"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">IT Strategy & Planning</h3>
|
||||
<p class="text-gray-600">
|
||||
Develop technology roadmaps aligned with business objectives
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/infrastructure.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Infrastructure Management"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Infrastructure Management</h3>
|
||||
<p class="text-gray-600">
|
||||
Design and implement robust IT infrastructure solutions
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/security.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Cybersecurity"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Cybersecurity</h3>
|
||||
<p class="text-gray-600">
|
||||
Protect your assets with advanced security measures
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/barchart.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Management Consulting"
|
||||
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Management Consulting</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Strategic business solutions to improve efficiency and drive growth.
|
||||
</p>
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/management-consulting.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Process Optimization"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Process Optimization</h3>
|
||||
<p class="text-gray-600">
|
||||
Streamline operations and improve business efficiency
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/people.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Change Management"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Change Management</h3>
|
||||
<p class="text-gray-600">
|
||||
Guide organizational transformation effectively
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/barchart.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Financial Analysis"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Financial Analysis</h3>
|
||||
<p class="text-gray-600">
|
||||
Data-driven financial planning and optimization
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-16">
|
||||
<div class="flex items-center mb-8">
|
||||
<img
|
||||
src="img/infrastructure.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Infrastructure Services"
|
||||
class="lucide lucide-shield w-8 h-8 text-blue-600 mr-4"
|
||||
/>
|
||||
<h2 class="text-3xl font-bold">Infrastructure Services</h2>
|
||||
</div>
|
||||
<p class="text-lg text-gray-600 mb-8">
|
||||
Build robust foundations for your business success
|
||||
</p>
|
||||
<div class="grid md:grid-cols-3 gap-8">
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/cloud.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Cloud Solutions"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Cloud Solutions</h3>
|
||||
<p class="text-gray-600">
|
||||
Leverage cloud technology for scalable solutions
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/network.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="Network Design"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">Network Design</h3>
|
||||
<p class="text-gray-600">
|
||||
Create secure and efficient network architectures
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="bg-white rounded-lg p-6 shadow-lg hover:shadow-xl transition-shadow"
|
||||
>
|
||||
<img
|
||||
src="img/system-integration.svg"
|
||||
height="24"
|
||||
width="24"
|
||||
alt="System Integration"
|
||||
class="lucide lucide-trending-up w-12 h-12 text-blue-600 mb-4"
|
||||
/>
|
||||
<h3 class="text-xl font-bold mb-3">System Integration</h3>
|
||||
<p class="text-gray-600">
|
||||
Seamlessly integrate systems for optimal performance
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-blue-600 text-white py-12">
|
||||
<div class="container mx-auto px-6 text-center">
|
||||
<h2 class="text-3xl font-bold mb-4">Need Customized Solutions?</h2>
|
||||
<p class="text-xl mb-6">
|
||||
Let's discuss how we can help transform your business
|
||||
</p>
|
||||
<button class="bigbutton">
|
||||
<a href="mailto:info@allucanget.biz">Schedule Consultation</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
from lib.markdown_parser import markdown_to_html_lines
|
||||
|
||||
|
||||
def test_external_link_gets_target_rel():
|
||||
md = '[external](https://example.com)'
|
||||
html = markdown_to_html_lines(md)
|
||||
assert 'href="https://example.com"' in html
|
||||
assert 'target="_blank"' in html
|
||||
assert 'rel="noopener noreferrer"' in html
|
||||
|
||||
|
||||
def test_internal_link_no_target():
|
||||
md = '[internal](/about)'
|
||||
html = markdown_to_html_lines(md)
|
||||
assert 'href="/about"' in html
|
||||
assert 'target=' not in html
|
||||
@@ -0,0 +1,133 @@
|
||||
import textwrap
|
||||
from lib import markdown_parser
|
||||
|
||||
|
||||
def make_empty_state():
|
||||
return {
|
||||
'page': {'title': None, 'sections': []},
|
||||
'current_section': None,
|
||||
'current_card': None,
|
||||
'current_detail': None,
|
||||
'content_buffer': [],
|
||||
'detail_buffer': [],
|
||||
}
|
||||
|
||||
|
||||
def test_flush_detail_buffer():
|
||||
state = make_empty_state()
|
||||
state['current_detail'] = {'title': 'D', 'content': ''}
|
||||
state['detail_buffer'] = ['Line 1', 'Line 2']
|
||||
|
||||
markdown_parser.flush_detail_buffer(state)
|
||||
|
||||
assert 'Line 1' in state['current_detail']['content']
|
||||
assert state['detail_buffer'] == []
|
||||
|
||||
|
||||
def test_flush_content_buffer_to_card():
|
||||
state = make_empty_state()
|
||||
state['current_card'] = {'title': 'C', 'content': ''}
|
||||
state['content_buffer'] = ['para 1', 'para 2']
|
||||
|
||||
markdown_parser.flush_content_buffer_to_card(state)
|
||||
|
||||
assert 'para 1' in state['current_card']['content']
|
||||
|
||||
|
||||
def test_flush_content_buffer_to_section():
|
||||
state = make_empty_state()
|
||||
state['current_section'] = {'title': 'S', 'content': '', 'cards': []}
|
||||
state['content_buffer'] = ['a', 'b']
|
||||
|
||||
markdown_parser.flush_content_buffer_to_section(state)
|
||||
|
||||
assert 'a' in state['current_section']['content']
|
||||
|
||||
|
||||
def test_start_section_and_card_and_detail_and_process_line():
|
||||
state = make_empty_state()
|
||||
|
||||
# start a section
|
||||
markdown_parser.start_section('Sec1', state)
|
||||
assert state['current_section']['title'] == 'Sec1'
|
||||
assert state['page']['sections'][0]['title'] == 'Sec1'
|
||||
|
||||
# start a card
|
||||
markdown_parser.start_card('Card1', state)
|
||||
assert state['current_card']['title'] == 'Card1'
|
||||
assert state['page']['sections'][0]['cards'][0]['title'] == 'Card1'
|
||||
|
||||
# start a detail
|
||||
markdown_parser.start_detail('Det1', state)
|
||||
assert state['current_detail']['title'] == 'Det1'
|
||||
|
||||
# process a normal content line into detail_buffer
|
||||
markdown_parser.process_line_with_state('Detail line 1', state)
|
||||
assert 'Detail line 1' in state['detail_buffer'][0]
|
||||
|
||||
# process an H3 to start a new card
|
||||
markdown_parser.process_line_with_state('### NewCard', state)
|
||||
assert state['current_card']['title'] == 'NewCard'
|
||||
|
||||
# process an H2 to start a new section
|
||||
markdown_parser.process_line_with_state('## NewSection', state)
|
||||
assert state['current_section']['title'] == 'NewSection'
|
||||
|
||||
|
||||
def test_start_card_without_section_is_noop():
|
||||
state = make_empty_state()
|
||||
|
||||
markdown_parser.start_card('Orphan', state)
|
||||
|
||||
assert state['current_card'] is None
|
||||
assert state['page']['sections'] == []
|
||||
|
||||
|
||||
def test_start_detail_without_card_is_noop():
|
||||
state = make_empty_state()
|
||||
|
||||
markdown_parser.start_detail('Detail', state)
|
||||
|
||||
assert state['current_detail'] is None
|
||||
assert state['detail_buffer'] == []
|
||||
|
||||
|
||||
def test_process_h4_without_card_is_treated_as_content():
|
||||
state = make_empty_state()
|
||||
|
||||
markdown_parser.process_line_with_state('#### Heading without card', state)
|
||||
|
||||
assert '#### Heading without card' in state['content_buffer']
|
||||
|
||||
|
||||
def test_process_new_h1_flushes_section_content():
|
||||
state = make_empty_state()
|
||||
markdown_parser.start_section('First', state)
|
||||
state['content_buffer'].append('Paragraph text')
|
||||
|
||||
markdown_parser.process_line_with_state('# New Page', state)
|
||||
|
||||
assert 'Paragraph text' in state['page']['sections'][0]['content']
|
||||
assert state['page']['title'] == 'New Page'
|
||||
|
||||
|
||||
def test_build_component_structure_matches_integration():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section A
|
||||
|
||||
### Card A
|
||||
Intro A
|
||||
|
||||
#### Detail X
|
||||
Line X
|
||||
""")
|
||||
|
||||
page = markdown_parser.build_component_structure(md, 'f.md')
|
||||
assert page['title'] == 'Title'
|
||||
assert page['sections'][0]['title'] == 'Section A'
|
||||
card = page['sections'][0]['cards'][0]
|
||||
assert card['title'] == 'Card A'
|
||||
assert 'Intro A' in card['content']
|
||||
assert 'Detail X' in card['details'][0]['title']
|
||||
@@ -0,0 +1,351 @@
|
||||
import textwrap
|
||||
import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
from markdown import Markdown
|
||||
from xml.etree.ElementTree import Element, SubElement
|
||||
from lib.markdown_parser import (
|
||||
HeadingCollector,
|
||||
HeadingExtension,
|
||||
build_component_structure,
|
||||
markdown_to_html_lines,
|
||||
parse_markdown_file,
|
||||
)
|
||||
|
||||
|
||||
def test_h4_creates_card_details():
|
||||
md = textwrap.dedent("""
|
||||
# Page Title
|
||||
|
||||
## Section One
|
||||
|
||||
### Card One
|
||||
Card intro paragraph.
|
||||
|
||||
#### Detail A
|
||||
Detail content line 1.
|
||||
- item 1
|
||||
- item 2
|
||||
|
||||
#### Detail B
|
||||
Another detail paragraph with [a link](https://example.com).
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
assert page['title'] == 'Page Title'
|
||||
assert len(page['sections']) == 1
|
||||
section = page['sections'][0]
|
||||
assert section['title'] == 'Section One'
|
||||
assert len(section['cards']) == 1
|
||||
card = section['cards'][0]
|
||||
assert card['title'] == 'Card One'
|
||||
# content should include the intro paragraph converted to HTML
|
||||
assert 'Card intro paragraph' in card['content']
|
||||
# details should be present
|
||||
assert 'details' in card
|
||||
assert len(card['details']) == 2
|
||||
assert card['details'][0]['title'] == 'Detail A'
|
||||
assert 'item 1' in card['details'][0]['content']
|
||||
assert card['details'][1]['title'] == 'Detail B'
|
||||
assert 'https://example.com' in card['details'][1]['content']
|
||||
|
||||
|
||||
def test_section_content_preserves_lists_before_first_card():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section One
|
||||
|
||||
- Item A
|
||||
- Item B
|
||||
|
||||
### Card Title
|
||||
Card body
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
section = page['sections'][0]
|
||||
assert '<ul>' in section['content']
|
||||
assert '<li>Item A</li>' in section['content']
|
||||
assert section['cards'][0]['title'] == 'Card Title'
|
||||
|
||||
|
||||
def test_card_content_keeps_lists_when_section_changes():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section One
|
||||
|
||||
### Card One
|
||||
- First
|
||||
- Second
|
||||
|
||||
## Section Two
|
||||
Details
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
first_section = page['sections'][0]
|
||||
card = first_section['cards'][0]
|
||||
assert '<ul>' in card['content']
|
||||
assert '<li>First</li>' in card['content']
|
||||
|
||||
|
||||
def test_card_body_renders_list_items():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section
|
||||
|
||||
### Card
|
||||
- Alpha
|
||||
- Beta
|
||||
- Gamma
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
card = page['sections'][0]['cards'][0]
|
||||
assert '<ul>' in card['content']
|
||||
assert '<li>Alpha</li>' in card['content']
|
||||
assert '<li>Gamma</li>' in card['content']
|
||||
|
||||
|
||||
def test_external_links_add_target_attributes():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section
|
||||
|
||||
Visit [Example](https://example.com) now.
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
section_html = page['sections'][0]['content']
|
||||
soup = BeautifulSoup(section_html, 'html.parser')
|
||||
anchor = soup.find('a')
|
||||
assert anchor is not None
|
||||
assert anchor['href'] == 'https://example.com'
|
||||
assert anchor.get('target') == '_blank'
|
||||
assert anchor.get('rel') == ['noopener', 'noreferrer']
|
||||
|
||||
|
||||
def test_unsafe_links_are_neutralized():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section
|
||||
|
||||
[Bad](javascript:alert('xss'))
|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "test.md")
|
||||
|
||||
section_html = page['sections'][0]['content']
|
||||
soup = BeautifulSoup(section_html, 'html.parser')
|
||||
anchor = soup.find('a')
|
||||
assert anchor is not None
|
||||
assert anchor['href'] == '#unsafe'
|
||||
assert 'target' not in anchor.attrs
|
||||
assert 'rel' not in anchor.attrs
|
||||
|
||||
|
||||
def test_index_page_sections_and_headings_extracted():
|
||||
text = """
|
||||
# Title
|
||||
|
||||
Main intro paragraph.
|
||||
|
||||
## Section 1
|
||||
|
||||
Section 1 intro.
|
||||
|
||||
- List item 1 a
|
||||
- List item 1 b
|
||||
|
||||
## Section 2
|
||||
|
||||
Section 2 intro.
|
||||
|
||||
- List item 2 a
|
||||
- List item 2 b
|
||||
|
||||
"""
|
||||
md = Markdown(extensions=[HeadingExtension()])
|
||||
md.convert(text)
|
||||
collector = md.treeprocessors['heading_collector']
|
||||
headings = [h for h in getattr(collector, 'headings', []) if 'level' in h]
|
||||
|
||||
assert headings[0]['level'] == 1
|
||||
assert headings[0]['text'] == 'Title'
|
||||
assert headings[1]['level'] == 2
|
||||
assert headings[1]['text'] == 'Section 1'
|
||||
assert headings[2]['level'] == 2
|
||||
assert headings[2]['text'] == 'Section 2'
|
||||
|
||||
|
||||
def test_index_page_main_intro_extracted():
|
||||
text = """
|
||||
# Title
|
||||
|
||||
This is the main introduction paragraph for the index page.
|
||||
|
||||
## Section 1
|
||||
|
||||
Section content.
|
||||
"""
|
||||
md = Markdown(extensions=[HeadingExtension()])
|
||||
md.convert(text)
|
||||
collector = md.treeprocessors['heading_collector']
|
||||
main_intro = getattr(collector, 'main_intro', '')
|
||||
|
||||
assert 'This is the main introduction paragraph for the index page.' in main_intro
|
||||
|
||||
|
||||
def test_heading_extension_collects_headings_and_lists():
|
||||
md = Markdown(extensions=[HeadingExtension()])
|
||||
md.convert(textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section with **Bold** and [Link](#target)
|
||||
|
||||
- Item A
|
||||
- [Item B](#b) and more
|
||||
"""))
|
||||
|
||||
collector = md.treeprocessors['heading_collector']
|
||||
headings = getattr(collector, 'headings', [])
|
||||
|
||||
assert headings[0]['level'] == 1
|
||||
assert headings[0]['text'] == 'Title'
|
||||
assert headings[1]['level'] == 2
|
||||
assert headings[1]['text'] == 'Section with Bold and Link'
|
||||
list_entry = next(entry for entry in headings if entry.get('type') == 'ul')
|
||||
assert list_entry['items'][0] == 'Item A'
|
||||
assert 'Item B' in list_entry['items'][1]
|
||||
|
||||
|
||||
def test_heading_collector_extract_text_handles_children():
|
||||
collector = HeadingCollector(Markdown())
|
||||
parent = Element('p')
|
||||
child = SubElement(parent, 'strong')
|
||||
child.text = 'Bold'
|
||||
child.tail = ' tail'
|
||||
nested = SubElement(child, 'em')
|
||||
nested.text = 'inner'
|
||||
|
||||
text = collector._extract_text(parent)
|
||||
|
||||
assert 'Bold' in text
|
||||
assert 'tail' in text
|
||||
assert 'inner' in text
|
||||
|
||||
collector.headings = []
|
||||
collector._process_element(parent)
|
||||
assert collector.headings == []
|
||||
|
||||
|
||||
def test_parse_markdown_file_sets_title_from_filename(tmp_path):
|
||||
file_path = tmp_path / 'sample_page.md'
|
||||
file_path.write_text('Just text without heading', encoding='utf-8')
|
||||
|
||||
page = parse_markdown_file(str(file_path))
|
||||
|
||||
assert page['title'] == 'Sample Page'
|
||||
|
||||
|
||||
def test_parse_markdown_file_missing(tmp_path):
|
||||
missing = tmp_path / 'not_there.md'
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
parse_markdown_file(str(missing))
|
||||
|
||||
|
||||
def test_markdown_to_html_lines_handles_empty_and_blank_links():
|
||||
assert markdown_to_html_lines('') == ''
|
||||
|
||||
html = markdown_to_html_lines(
|
||||
'Before [Empty]() and [External](https://example.com)')
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
anchors = soup.find_all('a')
|
||||
|
||||
assert anchors[0]['href'] == ''
|
||||
assert 'target' not in anchors[0].attrs
|
||||
assert anchors[1]['target'] == '_blank'
|
||||
|
||||
|
||||
def test_markdown_images_normalize_src_and_alt():
|
||||
html = markdown_to_html_lines(
|
||||
'')
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
image = soup.find('img')
|
||||
|
||||
assert image is not None
|
||||
assert image['src'] == 'img/it-consulting.svg'
|
||||
assert image['alt'] == 'IT Consulting'
|
||||
|
||||
|
||||
def test_markdown_images_add_alt_fallback():
|
||||
html = markdown_to_html_lines('')
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
image = soup.find('img')
|
||||
|
||||
assert image is not None
|
||||
assert image['src'] == 'img/logo.svg'
|
||||
assert image['alt'] == 'logo'
|
||||
|
||||
|
||||
def test_markdown_heading_with_inline_image_preserves_image():
|
||||
html = markdown_to_html_lines('## Heading ')
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
heading = soup.find('h2')
|
||||
image = heading.find('img') if heading else None
|
||||
|
||||
assert heading is not None
|
||||
assert heading.get_text(strip=True) == 'Heading'
|
||||
assert image is not None
|
||||
assert image['src'] == 'img/graphic.svg'
|
||||
assert image['alt'] == 'Graphic'
|
||||
|
||||
|
||||
def test_build_component_structure_converts_section_images():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section With Visual
|
||||
|
||||
Intro text before image.
|
||||
|
||||

|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "section.md")
|
||||
section_html = page['sections'][0]['content']
|
||||
soup = BeautifulSoup(section_html, 'html.parser')
|
||||
image = soup.find('img')
|
||||
|
||||
assert image is not None
|
||||
assert image['src'] == 'img/vision.png'
|
||||
assert image['alt'] == 'Vision Diagram'
|
||||
|
||||
|
||||
def test_build_component_structure_preserves_external_image_src():
|
||||
md = textwrap.dedent("""
|
||||
# Title
|
||||
|
||||
## Section
|
||||
|
||||

|
||||
""")
|
||||
|
||||
page = build_component_structure(md, "external.md")
|
||||
section_html = page['sections'][0]['content']
|
||||
soup = BeautifulSoup(section_html, 'html.parser')
|
||||
image = soup.find('img')
|
||||
|
||||
assert image is not None
|
||||
assert image['src'] == 'https://cdn.example.com/logo.svg'
|
||||
assert image['alt'] == 'Remote Logo'
|
||||
@@ -0,0 +1,15 @@
|
||||
from lib.markdown_parser import markdown_to_html_lines
|
||||
|
||||
|
||||
def test_javascript_link_neutralized():
|
||||
md = '[bad](javascript:alert(1))'
|
||||
html = markdown_to_html_lines(md)
|
||||
assert 'href="#unsafe"' in html
|
||||
assert 'javascript:' not in html
|
||||
|
||||
|
||||
def test_data_link_neutralized():
|
||||
md = '[bad](data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==)'
|
||||
html = markdown_to_html_lines(md)
|
||||
assert 'href="#unsafe"' in html
|
||||
assert 'data:' not in html
|
||||
@@ -0,0 +1,101 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from lib.utils import (
|
||||
get_template_files,
|
||||
render_template,
|
||||
set_active_page_by_url,
|
||||
minify_html,
|
||||
js_minifier,
|
||||
)
|
||||
|
||||
|
||||
def test_get_template_files_filters_partials_and_non_html(
|
||||
tmp_path: Path) -> None:
|
||||
template_dir = tmp_path / "templates"
|
||||
template_dir.mkdir()
|
||||
(template_dir / "page.html").write_text("<h1>Page</h1>", encoding="utf-8")
|
||||
(template_dir / "_partial.html").write_text("<p>Ignore</p>", encoding="utf-8")
|
||||
(template_dir / "notes.txt").write_text("ignore", encoding="utf-8")
|
||||
|
||||
result = get_template_files(str(template_dir))
|
||||
|
||||
assert sorted(result) == ["page.html"]
|
||||
|
||||
|
||||
def test_render_template_renders_with_context(tmp_path: Path) -> None:
|
||||
template_dir = tmp_path / "templates"
|
||||
template_dir.mkdir()
|
||||
(template_dir /
|
||||
"hello.html").write_text("Hello {{ name }}!", encoding="utf-8")
|
||||
|
||||
rendered = render_template(
|
||||
"hello.html", {
|
||||
"name": "World"}, template_dir=str(template_dir))
|
||||
|
||||
assert rendered == "Hello World!"
|
||||
|
||||
|
||||
def test_set_active_page_by_url_marks_only_requested_page_active() -> None:
|
||||
nav = {
|
||||
"index.html": {"active": False},
|
||||
"about.html": {"active": False},
|
||||
}
|
||||
|
||||
set_active_page_by_url(nav, "about.html")
|
||||
|
||||
assert nav["about.html"]["active"] is True
|
||||
assert nav["index.html"]["active"] is False
|
||||
|
||||
|
||||
def test_minify_html_removes_comments_and_extra_whitespace() -> None:
|
||||
html = "<div> Text </div> <!-- comment -->\n"
|
||||
|
||||
minified = minify_html(html)
|
||||
|
||||
assert minified == "<div> Text</div>"
|
||||
|
||||
|
||||
def test_js_minifier_strips_comments_and_rewrites_files(
|
||||
tmp_path: Path) -> None:
|
||||
output_dir = tmp_path / "site"
|
||||
js_dir = output_dir / "js"
|
||||
js_dir.mkdir(parents=True)
|
||||
js_path = js_dir / "app.js"
|
||||
js_path.write_text(
|
||||
"// comment\nvar x = 1; \n/* block */\nfunction test() { console.log(x); }\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
# Ensure non-JS files are ignored
|
||||
(js_dir / "readme.txt").write_text("skip", encoding="utf-8")
|
||||
|
||||
js_minifier(str(output_dir))
|
||||
|
||||
content = js_path.read_text(encoding="utf-8")
|
||||
|
||||
assert content == "var x = 1; function test() { console.log(x); }"
|
||||
assert os.path.exists(js_dir / "readme.txt")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"initial, expected",
|
||||
[
|
||||
({"a.js": "const a = 1;"}, "const a = 1;"),
|
||||
],
|
||||
)
|
||||
def test_js_minifier_handles_multiple_invocations(
|
||||
tmp_path: Path, initial, expected) -> None:
|
||||
output_dir = tmp_path / "dist"
|
||||
js_dir = output_dir / "js"
|
||||
js_dir.mkdir(parents=True)
|
||||
for filename, content in initial.items():
|
||||
(js_dir / filename).write_text(content, encoding="utf-8")
|
||||
|
||||
js_minifier(str(output_dir))
|
||||
js_minifier(str(output_dir))
|
||||
|
||||
for filename in initial:
|
||||
content = (js_dir / filename).read_text(encoding="utf-8")
|
||||
assert content == expected
|
||||