diff --git a/config/_default/languages/languages.en.yaml b/config/_default/languages/languages.en.yaml index ec70e1ef..84d07eed 100644 --- a/config/_default/languages/languages.en.yaml +++ b/config/_default/languages/languages.en.yaml @@ -4,28 +4,46 @@ params: weight: 1 home: Home description: | - We deal with data processing and capture of big life science data for social - sciences and humanities. + CAPRO helps social science and humanities projects at the University of Oslo + capture, process, manage and analyse large and complex data. copyright: Copyright © 2022 Capro banner: - title: Unlock Your Research Potential + title: We build the data workflows behind your research content: | - Whether you're conducting a study or developing a new product, don't let - technical skills hold you back. Contact us today to start realizing the true - potential of your research project. + CAPRO is a data engineering and data science team at the University of + Oslo. We help social science and humanities projects capture, process, + manage and analyse large and complex data. image: images/image-from-rawpixel-id-3337467-jpeg.jpg + buttons: + - label: What we can do + link: /services/ + style: primary + - label: Get in touch + link: "#contact" + style: outline + help: + title: How we can help + content: | + Six things we do for research projects. Each one can be a one-off piece of + advice, a workshop, or a full project collaboration. + button: + label: See all services in detail + link: /services/ + people: + title: The team button: - label: Our Services - link: "#services" + label: More about the team + link: /team/ contact: title: Contact Us - content: | - [Book a consultation](https://app.reclaim.ai/m/capro/initiating-talks) to - learn more about what we can offer. + email: capro-contact@psykologi.uio.no + intro: | + Tell us what you are stuck on and we will tell you honestly whether we can + help. The first conversation is free for UiO projects. item: - icon: ti-location-pin info: | - Harald Schjelderups hus, - Forskningsveien 3A, - 0373 Oslo + Harald Schjelderups hus,\ + Forskningsveien 3A,\ + 0373 Oslo,\ Norway diff --git a/config/_default/languages/languages.no.yaml b/config/_default/languages/languages.no.yaml index f4e710ee..0ce5814d 100644 --- a/config/_default/languages/languages.no.yaml +++ b/config/_default/languages/languages.no.yaml @@ -4,24 +4,46 @@ params: weight: 2 home: Hjem description: | - Vi jobber med dataprosessering og fanging av store livsvitenskapsdata - for samfunnsvitere og humaniora. + CAPRO hjelper prosjekter innen samfunnsvitenskap og humaniora ved + Universitetet i Oslo med å samle inn, prosessere, forvalte og analysere + store og komplekse data. copyright: Opphavsrett © 2022 Capro banner: - title: Hva kunne prosjektet ditt virkelig utrette - content: "Ikke sett deg fast i tekniske feller, la oss hjelpe deg!" + title: Vi bygger dataflyten bak forskningen din + content: | + CAPRO er et team for dataflyt og dataanalyse ved Universitetet i Oslo. Vi + hjelper prosjekter innen samfunnsvitenskap og humaniora med å samle inn, + prosessere, forvalte og analysere store og komplekse data. image: images/image-from-rawpixel-id-3337467-jpeg.jpg + buttons: + - label: Dette kan vi gjøre + link: /services/ + style: primary + - label: Ta kontakt + link: "#contact" + style: outline + help: + title: Slik kan vi hjelpe + content: | + Seks ting vi gjør for forskningsprosjekter. Hver av dem kan være et enkelt + råd, et kurs, eller et fullt prosjektsamarbeid. button: - label: Utforsk oss - link: "#services" + label: Se alle tjenestene i detalj + link: /services/ + people: + title: Teamet + button: + label: Mer om teamet + link: /team/ contact: title: Kontakt oss - content: | - [Book en time](https://app.reclaim.ai/m/capro/initiating-talks) for - konsultasjon om du ønsker mer informasjon om våre tjenester. + email: capro-contact@psykologi.uio.no + intro: | + Fortell oss hva du står fast på, så sier vi ærlig fra om vi kan hjelpe. + Den første samtalen er gratis for UiO-prosjekter. item: - icon: ti-location-pin info: | - Harald Schjelderups hus, - Forskningsveien 3A, + Harald Schjelderups hus,\ + Forskningsveien 3A,\ 0373 Oslo diff --git a/config/_default/menu.yaml b/config/_default/menu.yaml index 8f98a4ef..e85e88ca 100644 --- a/config/_default/menu.yaml +++ b/config/_default/menu.yaml @@ -1,19 +1,29 @@ +# Grouped by the question a visitor is asking, not by our org chart. +# "What we do" -> can you help me, have you done it before, what does it cost +# News -> a plain link; it is a feed, not a category +# Contact -> the action, never nested +# The team lives on the landing page and at /team/, linked from there and +# from the footer, so it does not need a nav slot of its own. main: + - identifier: whatwedo + weight: 1 - identifier: services - url: "#services" - weight: 2 + parent: whatwedo + url: /services/ + weight: 1 - identifier: portfolio - url: "#portfolio" - weight: 3 - - identifier: team - url: "#team" - weight: 4 + parent: whatwedo + url: /portfolio/ + weight: 2 - identifier: prices - url: "#pricing" - weight: 5 + parent: whatwedo + url: /pricing/ + weight: 3 + - identifier: news - url: "#news" - weight: 6 + url: /news/ + weight: 2 + - identifier: contact url: "#contact" - weight: 7 + weight: 3 diff --git a/content/about/_index.en.md b/content/about/_index.en.md index 1bde2c8b..ae44e99f 100644 --- a/content/about/_index.en.md +++ b/content/about/_index.en.md @@ -1,18 +1,28 @@ --- -title : About Us -item : - - icon : ti-ruler-pencil # themify icon pack : https://themify.me/themify-icons - title : We're Creative - content : | - We provide creative solutions to your data capturing and processing needs. - - - icon : ti-cup # themify icon pack : https://themify.me/themify-icons - title : We're Professional - content : | - Our staff has extensive knowledge in technical solutions for scientific work. - - - icon : ti-infinite # themify icon pack : https://themify.me/themify-icons - title : We bridge science & technology - content : | - We work in the intersection of science & technology to provide cutting-edge solutions. +title: About Us +item: + - icon: ti-user + title: A team inside the university + content: | + We are based at the Department of Psychology, University of Oslo, and work + with projects across the social sciences and humanities at UiO and beyond. + + - icon: ti-ruler-pencil + title: Engineers who have done research + content: | + Everyone on the team has worked in research. We know ethics approvals, + grant deadlines and what real data actually looks like when it arrives. + + - icon: ti-infinite + title: You own what we build + content: | + Code, documentation and workflows are handed over to you, so your project + keeps running long after our hours on it are finished. +build: + render: false + list: false --- + +CAPRO exists because capturing and processing large data has become central to +social science and humanities research, while the technical support for it has +not kept up. We fill that gap. diff --git a/content/about/_index.no.md b/content/about/_index.no.md index 7265b9bf..1e8f8e5f 100644 --- a/content/about/_index.no.md +++ b/content/about/_index.no.md @@ -1,21 +1,28 @@ --- -title : Om oss -item : - - icon : ti-ruler-pencil # themify icon pack : https://themify.me/themify-icons - title : Vi er kreative - content : | - Vi tilbyr kreative løsninger til dine behov for data fanging og prosessering. - - - icon : ti-cup # themify icon pack : https://themify.me/themify-icons - title : Vi er profesionelle - content : | - Våre ansatte har omfangende kunnskap - i tekniske løsninger for vitenskapelig - arbeid. - - - icon : ti-infinite # themify icon pack : https://themify.me/themify-icons - title : Vi binder sammen vitenskap & teknologi - content : | - Vi jobber midt mellom vitenskap & forskning, - for å tilby state-of-the-art hjelp. +title: Om oss +item: + - icon: ti-user + title: Et team inne i universitetet + content: | + Vi sitter ved Psykologisk institutt, Universitetet i Oslo, og jobber med + prosjekter innen samfunnsvitenskap og humaniora ved UiO og utenfor. + + - icon: ti-ruler-pencil + title: Ingeniører som har forsket selv + content: | + Alle i teamet har jobbet med forskning. Vi kjenner etikkgodkjenninger, + søknadsfrister og hvordan data faktisk ser ut når de kommer inn. + + - icon: ti-infinite + title: Du eier det vi bygger + content: | + Kode, dokumentasjon og arbeidsflyt overleveres til deg, slik at prosjektet + ditt går videre lenge etter at timene våre er brukt opp. +build: + render: false + list: false --- + +CAPRO finnes fordi innsamling og prosessering av store data har blitt sentralt i +samfunnsvitenskapelig og humanistisk forskning, mens den tekniske støtten ikke +har holdt følge. Det hullet fyller vi. diff --git a/content/cta/_index.en.md b/content/cta/_index.en.md index 43156311..5ab16dc0 100644 --- a/content/cta/_index.en.md +++ b/content/cta/_index.en.md @@ -4,6 +4,9 @@ button: label : "Start your project with us" link : "#contact" image_decorative: true +build: + render: false + list: false --- Don't wait with planning your data workflow, set it up from the start. diff --git a/content/cta/_index.no.md b/content/cta/_index.no.md index 56e72423..146dbf9f 100644 --- a/content/cta/_index.no.md +++ b/content/cta/_index.no.md @@ -4,6 +4,9 @@ button: label : "Ta kontakt for hjelp" link : "#contact" image_decorative: true +build: + render: false + list: false --- Ikke vent med å planlegge dataflyt for ditt prosjekt. diff --git a/content/feature/_index.en.md b/content/feature/_index.en.md index 4a197302..dabf1266 100644 --- a/content/feature/_index.en.md +++ b/content/feature/_index.en.md @@ -23,6 +23,9 @@ item: Our team offers custom solutions tailored to your project's specific needs and existing infrastructure, ensuring a workflow that best suits you and your team image_decorative: true +build: + render: false + list: false --- Capturing and processing large data sets is becoming increasingly important in social sciences and humanities, but project leaders can struggle with implementing the necessary technical solutions. We provide both standardized and customized solutions to meet your project needs and help set you and your team up for success. diff --git a/content/feature/_index.no.md b/content/feature/_index.no.md index 41ac3d95..9130dd58 100644 --- a/content/feature/_index.no.md +++ b/content/feature/_index.no.md @@ -32,6 +32,9 @@ item : for at akkurat ditt prosjekt og team kan får mest ut av dataene og jobbe effektivt. image_decorative: true +build: + render: false + list: false --- Det blir stadig viktigere for samfunnsvitere og humanioa å fange og prosessere store data. diff --git a/content/funfacts/_index.en.md b/content/funfacts/_index.en.md deleted file mode 100644 index f8f859d9..00000000 --- a/content/funfacts/_index.en.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -item: - - title : "Happy Clients" - icon : "fa-solid fa-face-smile-beam" - count : "20" - - - title : "Projects completed" - icon : "fa-solid fa-box-archive" - count : "11" - - - title : "Cups of Coffee" - icon : "fa-solid fa-mug-hot" - count : "250" -build: - render: false - list: false -image_decorative: true ---- diff --git a/content/funfacts/_index.no.md b/content/funfacts/_index.no.md deleted file mode 100644 index a4301ac8..00000000 --- a/content/funfacts/_index.no.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -item: - - title : "Fornøyde kunder" - icon : "fa-solid fa-face-smile-beam" - count : "20" - - - title : "Avsluttede prosjekter" - icon : "fa-solid fa-box-archive" - count : "11" - - - title : "Kaffekopper" - icon : "fa-solid fa-mug-hot" - count : "250" -build: - render: false - list: false -image_decorative: true ---- diff --git a/content/funfacts/bg-white-wall.jpg b/content/funfacts/bg-white-wall.jpg deleted file mode 100644 index 8c10e104..00000000 Binary files a/content/funfacts/bg-white-wall.jpg and /dev/null differ diff --git a/content/pricing/_index.en.md b/content/pricing/_index.en.md index f56edc72..2f3f3691 100644 --- a/content/pricing/_index.en.md +++ b/content/pricing/_index.en.md @@ -32,7 +32,7 @@ item : - If necessary, cost and time estimates for a project or workshop button: label : "Book a time" - link : "#book" + link : "#contact" - name : Project price : diff --git a/content/pricing/_index.no.md b/content/pricing/_index.no.md index 9bbf2cff..8918fe4c 100644 --- a/content/pricing/_index.no.md +++ b/content/pricing/_index.no.md @@ -32,7 +32,7 @@ item : - Om nødvendig, prisoverslag for et prosjekt eller kurs button: label : "Book en tid" - link : "#book" + link : "#contact" - name : Prosjekt price : diff --git a/content/service/_index.en.md b/content/services/_index.en.md similarity index 83% rename from content/service/_index.en.md rename to content/services/_index.en.md index f151f0a9..f9b6c89e 100644 --- a/content/service/_index.en.md +++ b/content/services/_index.en.md @@ -1,37 +1,44 @@ --- title: Our Scientific Services +aliases: + - /service/ item: - name: Statistical Programming Workshops icon: "fa-solid fa-chalkboard-user" + short: Hands-on training in R, Python and modern research workflows. content: | Mastering modern scientific software and workflows can be challenging for scientists. Our workshops provide hands-on training in popular open source programming languages and tools commonly used in scientific research to help you and your team get started. - + - name: Data Engineering icon: "fa-solid fa-hard-drive" + short: Getting your data in, cleaned, documented and safely stored. content: | Collecting and managing data and keeping track of its lineage is a critical aspect of scientific research. We can provide guidance and advice on obtaining, cleaning and securely managing your data, whether it be from publicly available sources or specialized methods. - + - name: Data Science & Containerization icon: "fa-solid fa-chart-line" + short: Processing, analysis and pipelines that run the same way twice. content: | Scientific data often requires significant processing and specific formats for analysis. We offer data analysis services, covering processing, formatting, and modeling. Our team has expertise in various methods and experience in implementing reproducible workflows using containerization for reproducibility. - + - name: High Performance Computing (HPC) icon: "fa-solid fa-server" + short: Running large analyses on national computing resources. content: | Analysing large and complex data sets in science often requires parallel computing. Our team has over a decade of experience in HPC and can help you with both acquiring and setting up resources for storage and processing of large datasets. - + - name: Applications & Databases icon: "fa-solid fa-tablet-screen-button" + short: Custom web apps and databases built around your project. content: | Customized software solutions can greatly enhance the efficiency of your research. We can develop web-based applications tailored to your specific needs, such as tracking and storing data and processing status, to help you identify and resolve issues early on. - + - name: Data Governance & FAIR principles icon: "fa-solid fa-folder-tree" + short: Structuring data so it stays findable, legal and reusable. content: | Proper data governance and adherence to FAIR principles are crucial for scientific research. We can provide guidance on structuring and managing your data to ensure it is discoverable, accessible, interoperable and reusable for the broader scientific community. - --- -Our services are specifically designed to support scientists in their research. +Our services are specifically designed to support scientists in their research. Browse our offerings to see how we can assist you in achieving your scientific goals. diff --git a/content/service/_index.no.md b/content/services/_index.no.md similarity index 54% rename from content/service/_index.no.md rename to content/services/_index.no.md index 69886c50..f9b7f162 100644 --- a/content/service/_index.no.md +++ b/content/services/_index.no.md @@ -1,44 +1,50 @@ --- -title : Våre tjenester -item : - - name : Kurs i statistikk / programmering - icon : ti-blackboard - content : | +title: Våre tjenester +item: + - name: Kurs i statistikk og programmering + icon: "fa-solid fa-chalkboard-user" + short: Praktiske kurs i R, Python og moderne arbeidsflyt for forskning. + content: | Å lære nye ferdigheter innen statistikk og programmering kan være vanskelig på - egenhånd. Vi tilbyr kurs på alle nivåer i bruk av open-source programspråk, verktøy, + egenhånd. Vi tilbyr kurs på alle nivåer i bruk av open-source programspråk, verktøy, og moderne arbeidsflyt. - - name : Datafangst - icon : ti-harddrives - content : | - Innsamling og preprossesering av data er ofte grunnstenen i moderne forskning. - Vi hjelper deg med å implementere systemer for å sikre at dataene dine er der + - name: Datafangst + icon: "fa-solid fa-hard-drive" + short: Få dataene inn, ryddet, dokumentert og trygt lagret. + content: | + Innsamling og preprossesering av data er ofte grunnstenen i moderne forskning. + Vi hjelper deg med å implementere systemer for å sikre at dataene dine er der når du trenger dem. Vi kan bistå med innhenting av åpne eller spesialiserte data. - - name : Prosessering & Analyse - icon : ti-stats-up - content : | + - name: Prosessering & analyse + icon: "fa-solid fa-chart-line" + short: Prosessering, analyse og arbeidsflyt som gir samme svar to ganger. + content: | Vitenskapelige data krever ofte betydelig bearbeiding og spesifikke formater for analyse. Vi tilbyr dataanalysetjenester som dekker prosessering, formatering og modellering. Teamet vårt har ekspertise på ulike metoder og erfaring med å implementere reproduserbar arbeidsflyt ved å bruke containerisering for reproduserbarhet. - - name : HPC / Tungregning - icon : ti-server - content : | + - name: HPC og tungregning + icon: "fa-solid fa-server" + short: Store analyser på nasjonale regneressurser. + content: | Store og kompleske data krever ofte parallellprosessering for effektivt arbeid. - Det krever spesialkunnskap å benytte HPC ressurser effektivt. Vi har over 10 år med - erfaring i tungregning, har god kjennskap til hvilke ressurser som eksisterer, og + Det krever spesialkunnskap å benytte HPC ressurser effektivt. Vi har over 10 år med + erfaring i tungregning, har god kjennskap til hvilke ressurser som eksisterer, og kan bistå i alle faser av prosjektet. - - name : Applikasjoner & databaser - icon : ti-package - content : | - Vi bygger webapplikasjoner og databaser som støtter innsamling og lagring av data, - slik at du og ditt team kan oppdage problemer raskere, og løse data- og flaskehalsproblemer + - name: Applikasjoner & databaser + icon: "fa-solid fa-tablet-screen-button" + short: Skreddersydde webapplikasjoner og databaser for prosjektet ditt. + content: | + Vi bygger webapplikasjoner og databaser som støtter innsamling og lagring av data, + slik at du og ditt team kan oppdage problemer raskere, og løse data- og flaskehalsproblemer så fort de oppstår. - - name : Åpne & FAIR data - icon : ti-zip - content : | - Vi tilbyr råd og hjelp til å bygge datastrukturer som forenkler senere bruk og deling. Ved å bygge datastrukturer og databaser riktig fra bunnen kan vi hjelpe deg gjøre dataene dine (mer)FAIR, og møte krav om åpne data fra finanskilder. + - name: Åpne & FAIR data + icon: "fa-solid fa-folder-tree" + short: Datastrukturer som holder dataene gjenfinnbare, lovlige og gjenbrukbare. + content: | + Vi tilbyr råd og hjelp til å bygge datastrukturer som forenkler senere bruk og deling. Ved å bygge datastrukturer og databaser riktig fra bunnen kan vi hjelpe deg gjøre dataene dine (mer) FAIR, og møte krav om åpne data fra finanskilder. --- Vi tilbyr en rekke tjenester for å hjelpe forskere nå deres prosjektmål. diff --git a/content/skill/_index.en.md b/content/skill/_index.en.md index d94be362..9e46f15d 100644 --- a/content/skill/_index.en.md +++ b/content/skill/_index.en.md @@ -16,6 +16,9 @@ item : - name : HPC analyses percent : 75% image_decorative: true +build: + render: false + list: false --- We’re skilled in translating the needs of social scientists into technical solutions to aid their work. diff --git a/content/skill/_index.no.md b/content/skill/_index.no.md index abe3b20f..df7f7e52 100644 --- a/content/skill/_index.no.md +++ b/content/skill/_index.no.md @@ -16,6 +16,9 @@ item : - name : HPC analyse percent : 75% image_decorative: true +build: + render: false + list: false --- Vi er dyktige på å oversette behovene til samfunnsvitere til tekniske løsninger som hjelper deres arbeid. diff --git a/content/team/_index.en.md b/content/team/_index.en.md index c5b39e7c..0e1e8fa0 100644 --- a/content/team/_index.en.md +++ b/content/team/_index.en.md @@ -1,5 +1,7 @@ --- title: Our Team +aliases: + - /about/ single: About Member --- diff --git a/content/testimonial/_index.en.md b/content/testimonial/_index.en.md index 7b1be3c0..4c50092b 100644 --- a/content/testimonial/_index.en.md +++ b/content/testimonial/_index.en.md @@ -1,5 +1,11 @@ --- title: Client testimonials +build: + render: false + list: false +cascade: + build: + render: false --- Don't take our word for it, listen to our clients! diff --git a/content/testimonial/_index.no.md b/content/testimonial/_index.no.md index f0fa4695..87659aab 100644 --- a/content/testimonial/_index.no.md +++ b/content/testimonial/_index.no.md @@ -1,5 +1,11 @@ --- title: Utsagn fra kunder +build: + render: false + list: false +cascade: + build: + render: false --- Ikke ta oss på vårt ord. diff --git a/i18n/en.yaml b/i18n/en.yaml index f3c23658..2d0e4278 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -1,11 +1,13 @@ # general - readMore: Read more -- viewAllPost: View All Posts - share: Share - authorsPosts: Posts by - authorsPubs: Publications by - all: All +- skipToContent: Skip to content +- emailUs: Email us + - skipToContent: Skip to content # Months @@ -23,9 +25,10 @@ - December: December # Menu +- whatwedo: What we do - services: Services -- portfolio: Portfolio -- team: Team +- portfolio: Our work +- team: The team - prices: Prices - news: News - contact: Contact diff --git a/i18n/no.yaml b/i18n/no.yaml index 15e6c6cf..aa28331e 100644 --- a/i18n/no.yaml +++ b/i18n/no.yaml @@ -1,12 +1,14 @@ # general - readMore: Les mer -- viewAllPost: Se alle poster - share: Del - authorsPosts: Poster av - authorsPubs: Publikasjoner av - all: Alle - contact: Kontakt +- skipToContent: Hopp til innhold +- emailUs: Send oss en e-post + - skipToContent: Hopp til innhold # Months @@ -24,9 +26,10 @@ - December: Desember # Menu +- whatwedo: Hva vi gjør - services: Tjenester -- portfolio: Portfolio -- team: Team +- portfolio: Vårt arbeid +- team: Teamet - prices: Priser - news: Nyheter - contact: Kontakt diff --git a/scripts/a11y/run.mjs b/scripts/a11y/run.mjs index 97353e97..885d74fb 100644 --- a/scripts/a11y/run.mjs +++ b/scripts/a11y/run.mjs @@ -236,8 +236,12 @@ for (const viewport of VIEWPORTS) { `${stops.size} distinct stops`, ); - // focus indicators - const fi = await page.evaluate(() => { + // Focus indicators. Only visible elements: a link inside a closed dropdown + // computes to outline-style:none, which is not a defect, and a check that + // cries wolf is a check people learn to ignore. + const probeFocus = () => { + const seen = (el) => + !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); const out = []; for (const s of [ 'a[href="#main"]', @@ -245,8 +249,9 @@ for (const viewport of VIEWPORTS) { 'footer a', '.nav-group__btn', 'header nav a', + '.nav-group__panel a', ]) { - const el = document.querySelector(s); + const el = [...document.querySelectorAll(s)].find(seen); if (!el) continue; el.focus(); const cs = getComputedStyle(el); @@ -257,8 +262,23 @@ for (const viewport of VIEWPORTS) { }); } return out; - }); - for (const f of fi) note(`focus indicator on ${f.s}`, f.ok, f.outline); + }; + for (const f of await page.evaluate(probeFocus)) { + note(`focus indicator on ${f.s}`, f.ok, f.outline); + } + // And again with the dropdown open, so its links are measurable. Open it + // with the keyboard, not a click: :focus-visible stops matching once the + // input modality is pointer, which reads as a missing focus ring. + const navBtn = await page.$('.nav-group__btn'); + if (navBtn) { + await navBtn.focus(); + await page.keyboard.press('Enter'); + await new Promise((r) => setTimeout(r, 350)); + for (const f of await page.evaluate(probeFocus)) { + if (f.s !== '.nav-group__panel a') continue; + note('focus indicator on an open dropdown link', f.ok, f.outline); + } + } await page.close(); } diff --git a/themes/capro-tw/assets/css/components/buttons.css b/themes/capro-tw/assets/css/components/buttons.css index 4efa01d4..2fa283cc 100644 --- a/themes/capro-tw/assets/css/components/buttons.css +++ b/themes/capro-tw/assets/css/components/buttons.css @@ -25,16 +25,15 @@ color: var(--color-primary-text); } - .btn-hero { - @apply px-14 py-5 text-lg font-bold uppercase tracking-widest; - background-color: var(--color-primary); - border: 2px solid var(--color-primary); + .btn-outline-light { + @apply border-2; + border-color: rgba(255, 255, 255, 0.5); color: #fff; } - .btn-hero:hover { - background-color: transparent; + .btn-outline-light:hover { border-color: #fff; - color: #fff; + background-color: #fff; + color: var(--color-dark); } } diff --git a/themes/capro-tw/assets/css/components/hero.css b/themes/capro-tw/assets/css/components/hero.css new file mode 100644 index 00000000..d82b0c13 --- /dev/null +++ b/themes/capro-tw/assets/css/components/hero.css @@ -0,0 +1,72 @@ +@layer components { + .banner { + min-height: min(100vh, 46rem); + } + + .banner h1 { + color: #fff; + max-width: 22ch; + margin-left: auto; + margin-right: auto; + } + + .banner-lead p { + font-size: 1.05rem; + color: #e8eaec; + max-width: 58ch; + margin: 0 auto; + } + + @media (min-width: 768px) { + .banner-lead p { + font-size: 1.2rem; + } + } + + .help-grid { + @apply grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3; + gap: 1px; + background-color: var(--color-border); + border: 1px solid var(--color-border); + list-style: none; + margin: 0; + padding: 0; + } + + .help-card { + @apply flex flex-col; + background-color: var(--color-dark); + padding: 32px 28px; + transition: background-color var(--transition-base); + } + + .help-card:hover { + background-color: var(--color-grey); + } + + .help-card i { + @apply mb-4 block; + font-size: 28px; + color: var(--color-primary-text); + } + + .help-card h3 { + @apply text-base font-medium mb-2; + color: var(--color-secondary); + } + + .help-card p { + font-size: 0.9rem; + line-height: 1.6; + color: var(--color-body); + margin: 0; + } + + .contact-map-frame { + border: 1px solid var(--color-border); + } + + .contact-map-frame #contact-map { + height: 260px; + } +} diff --git a/themes/capro-tw/assets/css/components/layout.css b/themes/capro-tw/assets/css/components/layout.css index ae50e01d..e151b1f5 100644 --- a/themes/capro-tw/assets/css/components/layout.css +++ b/themes/capro-tw/assets/css/components/layout.css @@ -26,6 +26,11 @@ color: var(--color-primary-text); } + .section-intro { + @apply max-w-2xl mx-auto text-center mb-12; + font-family: var(--font-serif); + } + .border-accent { border-top: 2px solid var(--color-border); height: 1px; @@ -81,7 +86,8 @@ } /* Links in running prose must be distinguishable without colour. */ - .prose a { + .prose a, + .section-intro a { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; diff --git a/themes/capro-tw/assets/css/components/nav.css b/themes/capro-tw/assets/css/components/nav.css index e1447c0d..4f432e48 100644 --- a/themes/capro-tw/assets/css/components/nav.css +++ b/themes/capro-tw/assets/css/components/nav.css @@ -47,4 +47,118 @@ border-color: var(--color-primary); color: #fff; } + + /* Grouped nav */ + .nav-group { + @apply relative; + } + + .nav-group__btn { + @apply inline-flex items-center gap-2 text-sm font-medium uppercase tracking-wider; + color: var(--color-body); + background: none; + border: 0; + cursor: pointer; + padding: 0; + transition: color var(--transition-fast); + } + + .nav-group__btn:hover, + .nav-group__btn.active { + color: var(--color-primary-text); + } + + .nav-group__chev { + transition: transform var(--transition-fast); + opacity: 0.7; + } + + .nav-group__chev--open { + transform: rotate(180deg); + } + + .nav-group__panel { + @apply absolute left-0 flex flex-col z-50; + top: calc(100% + 0.9rem); + min-width: 13rem; + padding: 0.5rem 0; + background-color: var(--color-dark); + border: 1px solid var(--color-border); + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); + } + + .nav-group__panel::before { + content: ""; + position: absolute; + left: 0; + right: 0; + top: -0.9rem; + height: 0.9rem; + } + + .nav-group__panel a { + @apply block text-sm normal-case tracking-normal; + padding: 0.6rem 1.1rem; + color: var(--color-body); + font-weight: 400; + letter-spacing: normal; + text-transform: none; + } + + .nav-group__panel a:hover, + .nav-group__panel a[aria-current="page"] { + background-color: var(--color-grey); + color: var(--color-primary-text); + } + + /* Mobile panel */ + .nav-mobile { + @apply absolute top-16 left-0 right-0 flex flex-col p-5 gap-1 z-50; + background-color: var(--color-dark); + border-top: 1px solid var(--color-border); + } + + .nav-mobile > a { + padding-block: 0.6rem; + } + + .nav-mobile__label { + @apply mt-4 mb-1; + font-family: var(--font-sans); + font-size: 0.68rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.13em; + color: var(--color-muted); + } + + .nav-mobile__label:first-child { + @apply mt-0; + } + + .nav-mobile__child { + padding-block: 0.6rem; + padding-left: 0.9rem; + border-left: 1px solid var(--color-border); + } + + .nav-mobile a[aria-current="page"] { + color: var(--color-primary-text); + } + + .footer-links { + @apply flex flex-wrap justify-center gap-x-7 gap-y-2 mb-8; + } + + .footer-links a { + @apply text-sm; + color: var(--color-muted); + text-transform: none; + letter-spacing: normal; + font-weight: 400; + } + + .footer-links a:hover { + color: var(--color-primary-text); + } } diff --git a/themes/capro-tw/assets/css/components/sections.css b/themes/capro-tw/assets/css/components/sections.css index ef2b046f..96b5d75c 100644 --- a/themes/capro-tw/assets/css/components/sections.css +++ b/themes/capro-tw/assets/css/components/sections.css @@ -98,36 +98,6 @@ transition: width 0.8s ease; } - /* Counters */ - .counter-card { - width: 200px; - height: 200px; - padding: 32px 24px; - background-color: var(--color-dark); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - } - - .counter-card i { - @apply mb-3 block; - font-size: 40px; - color: var(--color-light); - } - - .counter-card .counter-value { - font-size: 48px; - font-weight: 700; - color: var(--color-secondary); - } - - .counter-card h3 { - @apply mt-2; - font-size: 0.9rem; - color: var(--color-body); - } - /* Pricing */ .price-card { @apply h-full; @@ -224,13 +194,6 @@ margin: 0; } - /* Contact */ - .contact-icon { - @apply mr-4 mt-1; - font-size: 20px; - color: var(--color-primary-text); - } - /* Portfolio */ .portfolio-card { border: 1px solid var(--color-border); @@ -295,4 +258,39 @@ color: var(--color-light); margin-top: 8px; } + + /* Contact */ + .contact-email { + @apply text-center mb-14; + } + + .contact-email a { + @apply inline-block; + font-family: var(--font-sans); + font-size: clamp(1.1rem, 3vw, 1.8rem); + font-weight: 500; + letter-spacing: -0.015em; + color: var(--color-primary-text); + word-break: break-word; + padding-bottom: 4px; + border-bottom: 1px solid color-mix(in oklch, var(--color-primary) 45%, transparent); + transition: + color var(--transition-fast), + border-color var(--transition-fast); + } + + .contact-email a:hover, + .contact-email a:focus-visible { + color: var(--color-body); + border-bottom-color: var(--color-body); + } + + .contact-email__note { + @apply mt-3; + font-family: var(--font-sans); + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--color-muted); + } } diff --git a/themes/capro-tw/assets/css/components/team.css b/themes/capro-tw/assets/css/components/team.css index 9b7c4c94..2512a383 100644 --- a/themes/capro-tw/assets/css/components/team.css +++ b/themes/capro-tw/assets/css/components/team.css @@ -67,4 +67,26 @@ @apply text-xs; color: var(--color-light); } + + /* Compact variant used on the landing page: no bio, tighter meta. */ + .team-card--compact .team-meta { + padding: 12px 14px; + } + + .team-card--compact .team-meta h3 { + @apply text-base mb-0.5; + } + + .team-card--compact .team-meta h3 a { + color: var(--color-secondary); + } + + .team-card--compact:hover .team-meta h3 a { + color: var(--color-primary-text); + } + + /* Whole photo is the link when there is no social overlay to compete with. */ + .team-photo__link { + @apply absolute inset-0; + } } diff --git a/themes/capro-tw/assets/css/main.css b/themes/capro-tw/assets/css/main.css index 805a99a3..77745f78 100644 --- a/themes/capro-tw/assets/css/main.css +++ b/themes/capro-tw/assets/css/main.css @@ -145,6 +145,7 @@ @import "./components/layout.css"; @import "./components/nav.css"; @import "./components/buttons.css"; +@import "./components/hero.css"; @import "./components/sections.css"; @import "./components/team.css"; @import "./components/pubs.css"; diff --git a/themes/capro-tw/assets/css/vendor/tailwind.css b/themes/capro-tw/assets/css/vendor/tailwind.css index 7478b465..32ed5ea6 100644 --- a/themes/capro-tw/assets/css/vendor/tailwind.css +++ b/themes/capro-tw/assets/css/vendor/tailwind.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-tracking:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-sans:"Space Grotesk", sans-serif;--font-serif:"Spectral", serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--text-7xl:4.5rem;--text-7xl--line-height:1;--text-8xl:6rem;--text-8xl--line-height:1;--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--tracking-widest:.1em;--leading-relaxed:1.625;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-primary:#c04545;--color-primary-text:#e57575;--color-primary-dark:#b84444;--color-secondary:#85bfbf;--color-dark:#20242b;--color-grey:#2a2f36;--color-light:#8a8e93;--color-body:#d0d2d4;--color-muted:#9a9da0;--color-border:#eceff11f;--transition-fast:.2s ease;--transition-base:.3s ease;--transition-slow:.6s ease}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-300-normal.woff2)format("woff2");font-weight:300;font-display:swap}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-400-normal.woff2)format("woff2");font-weight:400;font-display:swap}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-500-normal.woff2)format("woff2");font-weight:500;font-display:swap}@font-face{font-family:Spectral;src:url(/webfonts/google-fonts/spectral/spectral-latin-300-normal.woff2)format("woff2");font-weight:300;font-display:swap}html{scroll-behavior:smooth;background-color:var(--color-grey);color:var(--color-body)}@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}body{font-family:var(--font-sans);-webkit-font-smoothing:antialiased;font-size:18px;line-height:1.6}@media (min-width:768px){body{font-size:20px}}h1,h2,h3,h4,h5,h6{font-family:var(--font-sans);color:var(--color-secondary);line-height:1.2}h1{font-weight:300}h2{font-weight:500}h3,h4,h5,h6{font-weight:400}p{font-family:var(--font-serif);color:var(--color-body);line-height:1.7}a{color:var(--color-secondary);transition:color var(--transition-fast);text-decoration:none}a:hover{color:var(--color-body)}:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}::selection{background:var(--color-primary);color:var(--color-body)}}@layer components{.section{padding-top:6rem;padding-bottom:6rem}@media (max-width:768px){.section{padding-top:3rem;padding-bottom:3rem}}.section-title{margin-bottom:calc(var(--spacing) * 12);text-align:center}.section-title h1,.section-title h2,.section-title__label{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);text-transform:capitalize;color:var(--color-body)}.section-title .accent{color:var(--color-primary-text)}.border-accent{border-top:2px solid var(--color-border);width:30%;height:1px;margin:15px auto 0;position:relative}.border-accent:before{content:"";background-color:var(--color-primary);width:50px;height:6px;margin-left:-25px;position:absolute;top:-4px;left:50%}.bg-dark{background-color:var(--color-dark)}.bg-grey{background-color:var(--color-grey)}.reveal{opacity:0;transition:opacity var(--transition-slow), transform var(--transition-slow);transform:translateY(24px)}.reveal.visible{opacity:1;transform:translateY(0)}.skip-link{left:calc(var(--spacing) * 4);z-index:100;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);background-color:var(--color-primary);color:#fff;transition:top var(--transition-fast);position:absolute;top:-100%}.skip-link:focus,.skip-link:focus-visible{color:#fff;top:.5rem}.prose a{text-underline-offset:3px;text-decoration:underline;text-decoration-thickness:1px}@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}}.prose pre,.highlight pre,.highlight{max-width:100%;overflow-x:auto}.prose table{max-width:100%;display:block;overflow-x:auto}.site-nav{top:calc(var(--spacing) * 0);z-index:50;background-color:var(--color-dark);transition:border-color var(--transition-base), box-shadow var(--transition-base);border-bottom:1px solid #0000;position:sticky}.site-nav.nav-scrolled{border-bottom-color:var(--color-border);box-shadow:0 2px 12px #0000004d}.site-nav a{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-body);transition:color var(--transition-fast)}.site-nav a:hover,.site-nav a.active{color:var(--color-primary-text)}.lang-select{cursor:pointer;border-style:var(--tw-border-style);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));appearance:none;background:var(--color-dark);color:var(--color-body);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d0d2d4' stroke-width='2' fill='none'/%3E%3C/svg%3E");background-position:right 6px center;background-repeat:no-repeat;border-width:0;padding:4px 24px 4px 8px}.footer-social-icon{height:calc(var(--spacing) * 12);width:calc(var(--spacing) * 12);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));color:var(--color-light);border:1px solid var(--color-border);transition:all var(--transition-base);border-radius:3.40282e38px;justify-content:center;align-items:center;display:flex}.footer-social-icon:hover{background-color:var(--color-primary);border-color:var(--color-primary);color:#fff}.btn{padding-inline:calc(var(--spacing) * 8);padding-block:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;transition:all var(--transition-fast);display:inline-block}.btn-primary{background-color:var(--color-primary-dark);color:#fff}.btn-primary:hover{background-color:var(--color-primary);color:#fff}.btn-outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border);color:var(--color-body)}.btn-outline:hover{border-color:var(--color-primary);color:var(--color-primary-text)}.btn-hero{padding-inline:calc(var(--spacing) * 14);padding-block:calc(var(--spacing) * 5);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest);text-transform:uppercase;background-color:var(--color-primary);border:2px solid var(--color-primary);color:#fff}.btn-hero:hover{color:#fff;background-color:#0000;border-color:#fff}.about-block{background:var(--color-dark);height:100%;transition:border-color var(--transition-base);border-bottom:2px solid #0000;padding:40px 32px}.about-block:hover{border-bottom-color:var(--color-primary)}.about-block:hover .icon-box{transform:translateY(-10px)}.about-block h3{color:var(--color-secondary)}.icon-box{border-left:2px solid var(--color-secondary);border-right:2px solid var(--color-secondary);width:160px;height:92px;color:var(--color-light);transition:transform var(--transition-base);z-index:1;background-color:#0000;justify-content:center;align-items:center;margin:46px auto 60px;padding:20px 0;font-size:36px;display:flex;position:relative}.icon-box:before,.icon-box:after{content:"";z-index:-1;background-color:var(--color-dark);width:113.14px;height:113.14px;position:absolute;left:20.43px;transform:scaleY(.5774)rotate(-45deg)}.icon-box:before{border-top:2px solid var(--color-secondary);border-right:2px solid var(--color-secondary);top:-56.57px}.icon-box:after{border-bottom:2px solid var(--color-secondary);border-left:2px solid var(--color-secondary);bottom:-56.57px}.service-block{text-align:center;background-color:var(--color-dark);border-left:1px solid var(--color-border);border-top:1px solid var(--color-border);height:100%;padding:60px 32px;box-shadow:2px 2px 5px #2c2c2c4d,13px 13px #ffffff1f}.service-block i{margin-bottom:calc(var(--spacing) * 6);color:var(--color-light);font-size:50px;display:block}.service-block h3{margin-bottom:calc(var(--spacing) * 3);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-secondary)}.progress-bar-track{background-color:var(--color-border);border-radius:3.40282e38px;width:100%;height:6px}.progress-bar-fill{background-color:var(--color-primary);border-radius:3.40282e38px;height:100%;transition:width .8s}.counter-card{background-color:var(--color-dark);flex-direction:column;justify-content:center;align-items:center;width:200px;height:200px;padding:32px 24px;display:flex}.counter-card i{margin-bottom:calc(var(--spacing) * 3);color:var(--color-light);font-size:40px;display:block}.counter-card .counter-value{color:var(--color-secondary);font-size:48px;font-weight:700}.counter-card h3{margin-top:calc(var(--spacing) * 2);color:var(--color-body);font-size:.9rem}.price-card{background-color:var(--color-dark);border:1px solid var(--color-border);height:100%;transition:border-color var(--transition-base);padding:40px 32px}.price-card h3{color:var(--color-secondary);margin-bottom:24px}.price-card table td{padding:6px 8px}.price-card:hover{border-color:var(--color-primary)}.testimonial-scroll{align-items:stretch;gap:calc(var(--spacing) * 6);scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:thin;scrollbar-color:var(--color-light) transparent;padding-bottom:16px;display:flex;overflow-x:auto}.testimonial-scroll::-webkit-scrollbar{height:6px}.testimonial-scroll::-webkit-scrollbar-track{background:0 0}.testimonial-scroll::-webkit-scrollbar-thumb{background:var(--color-light);border-radius:3px}.testimonial-nav{z-index:10;height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 10);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);background:var(--color-dark);border:1px solid var(--color-border);color:var(--color-body);transition:all var(--transition-fast);cursor:pointer;justify-content:center;align-items:center;display:flex;position:absolute;top:50%}.testimonial-nav:hover{border-color:var(--color-primary);color:var(--color-primary-text)}.testimonial-nav-left{left:-20px}.testimonial-nav-right{right:-20px}@media (max-width:768px){.testimonial-nav{display:none}}.testimonial-modern{background-color:var(--color-grey);border:1px solid var(--color-border);scroll-snap-align:start;width:360px;transition:border-color var(--transition-base);flex-direction:column;flex-shrink:0;padding:32px;display:flex}.testimonial-modern:hover{border-color:var(--color-primary)}.testimonial-modern blockquote{font-size:1rem;line-height:1.7}.testimonial-modern blockquote p{margin:0}.contact-icon{margin-top:calc(var(--spacing) * 1);margin-right:calc(var(--spacing) * 4);color:var(--color-primary-text);font-size:20px}.portfolio-card{border:1px solid var(--color-border);background-color:var(--color-dark);transition:border-color var(--transition-base)}.portfolio-card:hover{border-color:var(--color-primary)}.portfolio-card .portfolio-img{background:#fff;justify-content:center;align-items:center;height:16rem;padding:40px;display:flex;position:relative;overflow:hidden}.portfolio-card .portfolio-img img{object-fit:contain;width:auto;max-height:100%}.portfolio-card .portfolio-overlay{inset:calc(var(--spacing) * 0);opacity:0;transition:opacity var(--transition-base);background:#ffffffeb;justify-content:center;align-items:center;display:flex;position:absolute}.portfolio-card:hover .portfolio-overlay{opacity:1}.portfolio-card .portfolio-overlay .search-circle{background-color:var(--color-primary);color:#fff;border-radius:50%;justify-content:center;align-items:center;width:50px;height:50px;font-size:20px;display:flex}.portfolio-card .portfolio-meta{padding:20px}.portfolio-card .portfolio-meta h3{color:var(--color-secondary);font-size:1rem}.portfolio-card .portfolio-meta p{color:var(--color-light);margin-top:8px;font-size:.85rem}.team-card{border:1px solid var(--color-border);height:100%;transition:border-color var(--transition-base);background-color:#0000;flex-direction:column;display:flex;overflow:hidden}.team-card:hover{border-color:var(--color-primary)}.team-photo{position:relative;overflow:hidden}.team-photo img{width:100%;transition:transform var(--transition-base), filter var(--transition-base)}.team-photo:hover img{filter:brightness(1.15);transform:scale(1.05)}@media (prefers-contrast:more){.team-photo:hover img{filter:none}}.team-photo .social-overlay{inset:calc(var(--spacing) * 0);padding-bottom:calc(var(--spacing) * 5);opacity:0;background:linear-gradient(to top, var(--color-dark) 0%, transparent 60%);transition:opacity var(--transition-base);justify-content:center;align-items:flex-end;display:flex;position:absolute}.team-card:hover .social-overlay{opacity:1}.social-overlay a{margin-inline:calc(var(--spacing) * 1);height:calc(var(--spacing) * 9);width:calc(var(--spacing) * 9);text-align:center;font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-leading:calc(var(--spacing) * 9);line-height:calc(var(--spacing) * 9);color:var(--color-body);transition:color var(--transition-fast);display:inline-block}.social-overlay a:hover{color:var(--color-primary-text)}.team-meta{background-color:var(--color-dark);flex:1;padding:16px}.team-meta h3{margin-bottom:calc(var(--spacing) * 1);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.team-meta span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-light)}.pubs-table{width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-body)}.pubs-table th{padding-bottom:calc(var(--spacing) * 3);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-body);border-bottom:1px solid var(--color-border)}.pubs-table td{padding-block:calc(var(--spacing) * 3);vertical-align:top;border-bottom:1px solid var(--color-border)}.pubs-table .pub-year{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);font-family:var(--font-sans);color:var(--color-secondary)}.pubs-table .pub-authors{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);color:var(--color-muted)}.pubs-table .pub-title a{color:var(--color-secondary);transition:color var(--transition-fast)}.pubs-table .pub-title a:hover{color:var(--color-primary-text)}.pubs-table .pub-journal{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-muted);font-style:italic}.pubs-table tbody tr:hover td{color:var(--color-body)}.year-select{cursor:pointer;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);appearance:none;background:var(--color-dark);color:var(--color-body);border:1px solid var(--color-border);transition:border-color var(--transition-fast);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d0d2d4' stroke-width='2' fill='none'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;border-radius:4px;padding:8px 36px 8px 14px}.year-select:hover,.year-select:focus{border-color:var(--color-primary)}.year-select option{background:var(--color-dark);color:var(--color-body)}.footer-waves{background-color:var(--color-dark);height:60px;position:relative;overflow:hidden}.footer-waves svg{width:100%;height:100%;position:absolute;bottom:0;left:0}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-16{top:calc(var(--spacing) * 16)}.right-0{right:calc(var(--spacing) * 0)}.right-5{right:calc(var(--spacing) * 5)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-5{bottom:calc(var(--spacing) * 5)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-8{margin-top:calc(var(--spacing) * 8)}.mt-auto{margin-top:auto}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-24{height:calc(var(--spacing) * 24)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.min-h-\[400px\]{min-height:400px}.min-h-screen{min-height:100vh}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-48{width:calc(var(--spacing) * 48)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-none{max-width:none}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-12{gap:calc(var(--spacing) * 12)}.gap-16{gap:calc(var(--spacing) * 16)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-border{border-color:var(--color-border)}.border-primary{border-color:var(--color-primary)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-dark{background-color:var(--color-dark)}.bg-grey{background-color:var(--color-grey)}.bg-primary{background-color:var(--color-primary)}.bg-cover{background-size:cover}.bg-center{background-position:50%}.bg-top{background-position:top}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-8{padding:calc(var(--spacing) * 8)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-24{padding-block:calc(var(--spacing) * 24)}.py-28{padding-block:calc(var(--spacing) * 28)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-5xl{font-size:var(--text-5xl);line-height:var(--tw-leading,var(--text-5xl--line-height))}.text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-body{color:var(--color-body)}.text-light{color:var(--color-light)}.text-muted{color:var(--color-muted)}.text-primary{color:var(--color-primary)}.text-primary-text{color:var(--color-primary-text)}.text-secondary{color:var(--color-secondary)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.opacity-40{opacity:.4}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:border-primary:hover{border-color:var(--color-primary)}.hover\:bg-primary:hover{background-color:var(--color-primary)}.hover\:text-primary:hover{color:var(--color-primary)}.hover\:underline:hover{text-decoration-line:underline}}@media (min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:text-7xl{font-size:var(--text-7xl);line-height:var(--tw-leading,var(--text-7xl--line-height))}.md\:text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}}@media (min-width:64rem){.lg\:w-1\/2{width:50%}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:p-16{padding:calc(var(--spacing) * 16)}.lg\:text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}}}[x-cloak]{display:none!important}.leaflet-container .leaflet-control-attribution a{text-underline-offset:2px;text-decoration:underline}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0} \ No newline at end of file +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-tracking:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer theme{:root,:host{--font-sans:"Space Grotesk", sans-serif;--font-serif:"Spectral", serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-6xl:3.75rem;--text-6xl--line-height:1;--text-8xl:6rem;--text-8xl--line-height:1;--font-weight-light:300;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-normal:0em;--tracking-wider:.05em;--leading-relaxed:1.625;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-primary:#c04545;--color-primary-text:#e57575;--color-primary-dark:#b84444;--color-secondary:#85bfbf;--color-dark:#20242b;--color-grey:#2a2f36;--color-light:#8a8e93;--color-body:#d0d2d4;--color-muted:#9a9da0;--color-border:#eceff11f;--transition-fast:.2s ease;--transition-base:.3s ease;--transition-slow:.6s ease}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-300-normal.woff2)format("woff2");font-weight:300;font-display:swap}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-400-normal.woff2)format("woff2");font-weight:400;font-display:swap}@font-face{font-family:Space Grotesk;src:url(/webfonts/google-fonts/space-grotesk/space-grotesk-latin-500-normal.woff2)format("woff2");font-weight:500;font-display:swap}@font-face{font-family:Spectral;src:url(/webfonts/google-fonts/spectral/spectral-latin-300-normal.woff2)format("woff2");font-weight:300;font-display:swap}html{scroll-behavior:smooth;background-color:var(--color-grey);color:var(--color-body)}@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,:before,:after{transition-duration:.01ms!important;animation-duration:.01ms!important}}body{font-family:var(--font-sans);-webkit-font-smoothing:antialiased;font-size:18px;line-height:1.6}@media (min-width:768px){body{font-size:20px}}h1,h2,h3,h4,h5,h6{font-family:var(--font-sans);color:var(--color-secondary);line-height:1.2}h1{font-weight:300}h2{font-weight:500}h3,h4,h5,h6{font-weight:400}p{font-family:var(--font-serif);color:var(--color-body);line-height:1.7}a{color:var(--color-secondary);transition:color var(--transition-fast);text-decoration:none}a:hover{color:var(--color-body)}:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}::selection{background:var(--color-primary);color:var(--color-body)}}@layer components{.section{padding-top:6rem;padding-bottom:6rem}@media (max-width:768px){.section{padding-top:3rem;padding-bottom:3rem}}.section-title{margin-bottom:calc(var(--spacing) * 12);text-align:center}.section-title h1,.section-title h2,.section-title__label{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold);text-transform:capitalize;color:var(--color-body)}.section-title .accent{color:var(--color-primary-text)}.section-intro{margin-inline:auto;margin-bottom:calc(var(--spacing) * 12);max-width:var(--container-2xl);text-align:center;font-family:var(--font-serif)}.border-accent{border-top:2px solid var(--color-border);width:30%;height:1px;margin:15px auto 0;position:relative}.border-accent:before{content:"";background-color:var(--color-primary);width:50px;height:6px;margin-left:-25px;position:absolute;top:-4px;left:50%}.bg-dark{background-color:var(--color-dark)}.bg-grey{background-color:var(--color-grey)}.reveal{opacity:0;transition:opacity var(--transition-slow), transform var(--transition-slow);transform:translateY(24px)}.reveal.visible{opacity:1;transform:translateY(0)}.skip-link{left:calc(var(--spacing) * 4);z-index:100;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);background-color:var(--color-primary);color:#fff;transition:top var(--transition-fast);position:absolute;top:-100%}.skip-link:focus,.skip-link:focus-visible{color:#fff;top:.5rem}.prose a,.section-intro a{text-underline-offset:3px;text-decoration:underline;text-decoration-thickness:1px}@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}}.prose pre,.highlight pre,.highlight{max-width:100%;overflow-x:auto}.prose table{max-width:100%;display:block;overflow-x:auto}.site-nav{top:calc(var(--spacing) * 0);z-index:50;background-color:var(--color-dark);transition:border-color var(--transition-base), box-shadow var(--transition-base);border-bottom:1px solid #0000;position:sticky}.site-nav.nav-scrolled{border-bottom-color:var(--color-border);box-shadow:0 2px 12px #0000004d}.site-nav a{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-body);transition:color var(--transition-fast)}.site-nav a:hover,.site-nav a.active{color:var(--color-primary-text)}.lang-select{cursor:pointer;border-style:var(--tw-border-style);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));appearance:none;background:var(--color-dark);color:var(--color-body);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d0d2d4' stroke-width='2' fill='none'/%3E%3C/svg%3E");background-position:right 6px center;background-repeat:no-repeat;border-width:0;padding:4px 24px 4px 8px}.footer-social-icon{height:calc(var(--spacing) * 12);width:calc(var(--spacing) * 12);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));color:var(--color-light);border:1px solid var(--color-border);transition:all var(--transition-base);border-radius:3.40282e38px;justify-content:center;align-items:center;display:flex}.footer-social-icon:hover{background-color:var(--color-primary);border-color:var(--color-primary);color:#fff}.nav-group{position:relative}.nav-group__btn{align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-body);cursor:pointer;transition:color var(--transition-fast);background:0 0;border:0;padding:0;display:inline-flex}.nav-group__btn:hover,.nav-group__btn.active{color:var(--color-primary-text)}.nav-group__chev{transition:transform var(--transition-fast);opacity:.7}.nav-group__chev--open{transform:rotate(180deg)}.nav-group__panel{left:calc(var(--spacing) * 0);z-index:50;background-color:var(--color-dark);border:1px solid var(--color-border);flex-direction:column;min-width:13rem;padding:.5rem 0;display:flex;position:absolute;top:calc(100% + .9rem);box-shadow:0 10px 30px #0006}.nav-group__panel:before{content:"";height:.9rem;position:absolute;top:-.9rem;left:0;right:0}.nav-group__panel a{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal);color:var(--color-body);letter-spacing:normal;text-transform:none;padding:.6rem 1.1rem;font-weight:400;display:block}.nav-group__panel a:hover,.nav-group__panel a[aria-current=page]{background-color:var(--color-grey);color:var(--color-primary-text)}.nav-mobile{top:calc(var(--spacing) * 16);right:calc(var(--spacing) * 0);left:calc(var(--spacing) * 0);z-index:50;gap:calc(var(--spacing) * 1);padding:calc(var(--spacing) * 5);background-color:var(--color-dark);border-top:1px solid var(--color-border);flex-direction:column;display:flex;position:absolute}.nav-mobile>a{padding-block:.6rem}.nav-mobile__label{margin-top:calc(var(--spacing) * 4);margin-bottom:calc(var(--spacing) * 1);font-family:var(--font-sans);text-transform:uppercase;letter-spacing:.13em;color:var(--color-muted);font-size:.68rem;font-weight:600}.nav-mobile__label:first-child{margin-top:calc(var(--spacing) * 0)}.nav-mobile__child{border-left:1px solid var(--color-border);padding-block:.6rem;padding-left:.9rem}.nav-mobile a[aria-current=page]{color:var(--color-primary-text)}.footer-links{margin-bottom:calc(var(--spacing) * 8);justify-content:center;column-gap:calc(var(--spacing) * 7);row-gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.footer-links a{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-muted);text-transform:none;letter-spacing:normal;font-weight:400}.footer-links a:hover{color:var(--color-primary-text)}.btn{padding-inline:calc(var(--spacing) * 8);padding-block:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;transition:all var(--transition-fast);display:inline-block}.btn-primary{background-color:var(--color-primary-dark);color:#fff}.btn-primary:hover{background-color:var(--color-primary);color:#fff}.btn-outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border);color:var(--color-body)}.btn-outline:hover{border-color:var(--color-primary);color:var(--color-primary-text)}.btn-outline-light{border-style:var(--tw-border-style);color:#fff;border-width:2px;border-color:#ffffff80}.btn-outline-light:hover{color:var(--color-dark);background-color:#fff;border-color:#fff}.banner{min-height:min(100vh,46rem)}.banner h1{color:#fff;max-width:22ch;margin-left:auto;margin-right:auto}.banner-lead p{color:#e8eaec;max-width:58ch;margin:0 auto;font-size:1.05rem}@media (min-width:768px){.banner-lead p{font-size:1.2rem}}.help-grid{grid-template-columns:repeat(1,minmax(0,1fr));display:grid}@media (min-width:40rem){.help-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.help-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}.help-grid{background-color:var(--color-border);border:1px solid var(--color-border);gap:1px;margin:0;padding:0;list-style:none}.help-card{background-color:var(--color-dark);transition:background-color var(--transition-base);flex-direction:column;padding:32px 28px;display:flex}.help-card:hover{background-color:var(--color-grey)}.help-card i{margin-bottom:calc(var(--spacing) * 4);color:var(--color-primary-text);font-size:28px;display:block}.help-card h3{margin-bottom:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-secondary)}.help-card p{color:var(--color-body);margin:0;font-size:.9rem;line-height:1.6}.contact-map-frame{border:1px solid var(--color-border)}.contact-map-frame #contact-map{height:260px}.about-block{background:var(--color-dark);height:100%;transition:border-color var(--transition-base);border-bottom:2px solid #0000;padding:40px 32px}.about-block:hover{border-bottom-color:var(--color-primary)}.about-block:hover .icon-box{transform:translateY(-10px)}.about-block h3{color:var(--color-secondary)}.icon-box{border-left:2px solid var(--color-secondary);border-right:2px solid var(--color-secondary);width:160px;height:92px;color:var(--color-light);transition:transform var(--transition-base);z-index:1;background-color:#0000;justify-content:center;align-items:center;margin:46px auto 60px;padding:20px 0;font-size:36px;display:flex;position:relative}.icon-box:before,.icon-box:after{content:"";z-index:-1;background-color:var(--color-dark);width:113.14px;height:113.14px;position:absolute;left:20.43px;transform:scaleY(.5774)rotate(-45deg)}.icon-box:before{border-top:2px solid var(--color-secondary);border-right:2px solid var(--color-secondary);top:-56.57px}.icon-box:after{border-bottom:2px solid var(--color-secondary);border-left:2px solid var(--color-secondary);bottom:-56.57px}.service-block{text-align:center;background-color:var(--color-dark);border-left:1px solid var(--color-border);border-top:1px solid var(--color-border);height:100%;padding:60px 32px;box-shadow:2px 2px 5px #2c2c2c4d,13px 13px #ffffff1f}.service-block i{margin-bottom:calc(var(--spacing) * 6);color:var(--color-light);font-size:50px;display:block}.service-block h3{margin-bottom:calc(var(--spacing) * 3);font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-secondary)}.progress-bar-track{background-color:var(--color-border);border-radius:3.40282e38px;width:100%;height:6px}.progress-bar-fill{background-color:var(--color-primary);border-radius:3.40282e38px;height:100%;transition:width .8s}.price-card{background-color:var(--color-dark);border:1px solid var(--color-border);height:100%;transition:border-color var(--transition-base);padding:40px 32px}.price-card h3{color:var(--color-secondary);margin-bottom:24px}.price-card table td{padding:6px 8px}.price-card:hover{border-color:var(--color-primary)}.testimonial-scroll{align-items:stretch;gap:calc(var(--spacing) * 6);scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:thin;scrollbar-color:var(--color-light) transparent;padding-bottom:16px;display:flex;overflow-x:auto}.testimonial-scroll::-webkit-scrollbar{height:6px}.testimonial-scroll::-webkit-scrollbar-track{background:0 0}.testimonial-scroll::-webkit-scrollbar-thumb{background:var(--color-light);border-radius:3px}.testimonial-nav{z-index:10;height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 10);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);background:var(--color-dark);border:1px solid var(--color-border);color:var(--color-body);transition:all var(--transition-fast);cursor:pointer;justify-content:center;align-items:center;display:flex;position:absolute;top:50%}.testimonial-nav:hover{border-color:var(--color-primary);color:var(--color-primary-text)}.testimonial-nav-left{left:-20px}.testimonial-nav-right{right:-20px}@media (max-width:768px){.testimonial-nav{display:none}}.testimonial-modern{background-color:var(--color-grey);border:1px solid var(--color-border);scroll-snap-align:start;width:360px;transition:border-color var(--transition-base);flex-direction:column;flex-shrink:0;padding:32px;display:flex}.testimonial-modern:hover{border-color:var(--color-primary)}.testimonial-modern blockquote{font-size:1rem;line-height:1.7}.testimonial-modern blockquote p{margin:0}.portfolio-card{border:1px solid var(--color-border);background-color:var(--color-dark);transition:border-color var(--transition-base)}.portfolio-card:hover{border-color:var(--color-primary)}.portfolio-card .portfolio-img{background:#fff;justify-content:center;align-items:center;height:16rem;padding:40px;display:flex;position:relative;overflow:hidden}.portfolio-card .portfolio-img img{object-fit:contain;width:auto;max-height:100%}.portfolio-card .portfolio-overlay{inset:calc(var(--spacing) * 0);opacity:0;transition:opacity var(--transition-base);background:#ffffffeb;justify-content:center;align-items:center;display:flex;position:absolute}.portfolio-card:hover .portfolio-overlay{opacity:1}.portfolio-card .portfolio-overlay .search-circle{background-color:var(--color-primary);color:#fff;border-radius:50%;justify-content:center;align-items:center;width:50px;height:50px;font-size:20px;display:flex}.portfolio-card .portfolio-meta{padding:20px}.portfolio-card .portfolio-meta h3{color:var(--color-secondary);font-size:1rem}.portfolio-card .portfolio-meta p{color:var(--color-light);margin-top:8px;font-size:.85rem}.contact-email{margin-bottom:calc(var(--spacing) * 14);text-align:center}.contact-email a{font-family:var(--font-sans);letter-spacing:-.015em;color:var(--color-primary-text);word-break:break-word;border-bottom:1px solid #c0454573;padding-bottom:4px;font-size:clamp(1.1rem,3vw,1.8rem);font-weight:500;display:inline-block}@supports (color:color-mix(in lab, red, red)){.contact-email a{border-bottom:1px solid color-mix(in oklch, var(--color-primary) 45%, transparent)}}.contact-email a{transition:color var(--transition-fast), border-color var(--transition-fast)}.contact-email a:hover,.contact-email a:focus-visible{color:var(--color-body);border-bottom-color:var(--color-body)}.contact-email__note{margin-top:calc(var(--spacing) * 3);font-family:var(--font-sans);text-transform:uppercase;letter-spacing:.12em;color:var(--color-muted);font-size:.8rem}.team-card{border:1px solid var(--color-border);height:100%;transition:border-color var(--transition-base);background-color:#0000;flex-direction:column;display:flex;overflow:hidden}.team-card:hover{border-color:var(--color-primary)}.team-photo{position:relative;overflow:hidden}.team-photo img{width:100%;transition:transform var(--transition-base), filter var(--transition-base)}.team-photo:hover img{filter:brightness(1.15);transform:scale(1.05)}@media (prefers-contrast:more){.team-photo:hover img{filter:none}}.team-photo .social-overlay{inset:calc(var(--spacing) * 0);padding-bottom:calc(var(--spacing) * 5);opacity:0;background:linear-gradient(to top, var(--color-dark) 0%, transparent 60%);transition:opacity var(--transition-base);justify-content:center;align-items:flex-end;display:flex;position:absolute}.team-card:hover .social-overlay{opacity:1}.social-overlay a{margin-inline:calc(var(--spacing) * 1);height:calc(var(--spacing) * 9);width:calc(var(--spacing) * 9);text-align:center;font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-leading:calc(var(--spacing) * 9);line-height:calc(var(--spacing) * 9);color:var(--color-body);transition:color var(--transition-fast);display:inline-block}.social-overlay a:hover{color:var(--color-primary-text)}.team-meta{background-color:var(--color-dark);flex:1;padding:16px}.team-meta h3{margin-bottom:calc(var(--spacing) * 1);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.team-meta span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-light)}.team-card--compact .team-meta{padding:12px 14px}.team-card--compact .team-meta h3{margin-bottom:calc(var(--spacing) * .5);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.team-card--compact .team-meta h3 a{color:var(--color-secondary)}.team-card--compact:hover .team-meta h3 a{color:var(--color-primary-text)}.team-photo__link{inset:calc(var(--spacing) * 0);position:absolute}.pubs-table{width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-body)}.pubs-table th{padding-bottom:calc(var(--spacing) * 3);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-body);border-bottom:1px solid var(--color-border)}.pubs-table td{padding-block:calc(var(--spacing) * 3);vertical-align:top;border-bottom:1px solid var(--color-border)}.pubs-table .pub-year{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);font-family:var(--font-sans);color:var(--color-secondary)}.pubs-table .pub-authors{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);color:var(--color-muted)}.pubs-table .pub-title a{color:var(--color-secondary);transition:color var(--transition-fast)}.pubs-table .pub-title a:hover{color:var(--color-primary-text)}.pubs-table .pub-journal{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-muted);font-style:italic}.pubs-table tbody tr:hover td{color:var(--color-body)}.year-select{cursor:pointer;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);appearance:none;background:var(--color-dark);color:var(--color-body);border:1px solid var(--color-border);transition:border-color var(--transition-fast);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d0d2d4' stroke-width='2' fill='none'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;border-radius:4px;padding:8px 36px 8px 14px}.year-select:hover,.year-select:focus{border-color:var(--color-primary)}.year-select option{background:var(--color-dark);color:var(--color-body)}.footer-waves{background-color:var(--color-dark);height:60px;position:relative;overflow:hidden}.footer-waves svg{width:100%;height:100%;position:absolute;bottom:0;left:0}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.right-0{right:calc(var(--spacing) * 0)}.right-5{right:calc(var(--spacing) * 5)}.bottom-0{bottom:calc(var(--spacing) * 0)}.bottom-5{bottom:calc(var(--spacing) * 5)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-40{z-index:40}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing) * 6)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-12{margin-top:calc(var(--spacing) * 12)}.mt-auto{margin-top:auto}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.mb-10{margin-bottom:calc(var(--spacing) * 10)}.mb-12{margin-bottom:calc(var(--spacing) * 12)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-24{height:calc(var(--spacing) * 24)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.min-h-\[400px\]{min-height:400px}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-48{width:calc(var(--spacing) * 48)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-none{max-width:none}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-7{gap:calc(var(--spacing) * 7)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-16{gap:calc(var(--spacing) * 16)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-border{border-color:var(--color-border)}.border-primary{border-color:var(--color-primary)}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-black\/70{background-color:#000000b3}@supports (color:color-mix(in lab, red, red)){.bg-black\/70{background-color:color-mix(in oklab, var(--color-black) 70%, transparent)}}.bg-dark{background-color:var(--color-dark)}.bg-grey{background-color:var(--color-grey)}.bg-primary{background-color:var(--color-primary)}.bg-cover{background-size:cover}.bg-center{background-position:50%}.bg-top{background-position:top}.object-cover{object-fit:cover}.p-2{padding:calc(var(--spacing) * 2)}.p-5{padding:calc(var(--spacing) * 5)}.p-8{padding:calc(var(--spacing) * 8)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-24{padding-block:calc(var(--spacing) * 24)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-12{padding-bottom:calc(var(--spacing) * 12)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-serif{font-family:var(--font-serif)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-8xl{font-size:var(--text-8xl);line-height:var(--tw-leading,var(--text-8xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-body{color:var(--color-body)}.text-light{color:var(--color-light)}.text-muted{color:var(--color-muted)}.text-primary{color:var(--color-primary)}.text-primary-text{color:var(--color-primary-text)}.text-secondary{color:var(--color-secondary)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.opacity-40{opacity:.4}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:border-primary:hover{border-color:var(--color-primary)}.hover\:bg-primary:hover{background-color:var(--color-primary)}.hover\:text-primary:hover{color:var(--color-primary)}.hover\:underline:hover{text-decoration-line:underline}}@media (min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:48rem){.md\:flex{display:flex}.md\:hidden{display:none}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}}@media (min-width:64rem){.lg\:w-1\/2{width:50%}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}.lg\:p-16{padding:calc(var(--spacing) * 16)}}}[x-cloak]{display:none!important}.leaflet-container .leaflet-control-attribution a{text-underline-offset:2px;text-decoration:underline}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0} \ No newline at end of file diff --git a/themes/capro-tw/assets/js/counter.js b/themes/capro-tw/assets/js/counter.js deleted file mode 100644 index 6ca650e0..00000000 --- a/themes/capro-tw/assets/js/counter.js +++ /dev/null @@ -1,31 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - var counters = document.querySelectorAll('[data-count]'); - if (!counters.length) return; - - var observer = new IntersectionObserver( - function (entries) { - entries.forEach(function (entry) { - if (!entry.isIntersecting) return; - var el = entry.target; - var target = parseInt(el.dataset.count, 10); - var duration = 1200; - var start = performance.now(); - - function step(now) { - var progress = Math.min((now - start) / duration, 1); - el.textContent = Math.floor(progress * target); - if (progress < 1) requestAnimationFrame(step); - else el.textContent = target; - } - - requestAnimationFrame(step); - observer.unobserve(el); - }); - }, - { threshold: 0.5 }, - ); - - counters.forEach(function (el) { - observer.observe(el); - }); -}); diff --git a/themes/capro-tw/layouts/_default/list.html b/themes/capro-tw/layouts/_default/list.html index dbb82640..59685ff8 100644 --- a/themes/capro-tw/layouts/_default/list.html +++ b/themes/capro-tw/layouts/_default/list.html @@ -1,14 +1,9 @@ {{ define "main" }} +{{ $page := . }} {{ with .CurrentSection }}
- {{ with .Title }} - {{ $words := split . " " }} -
-

{{ index $words 0 | safeHTML }}{{ if gt (len $words) 1 }} {{ delimit (after 1 $words) " " | safeHTML }}{{ end }}

-
-
- {{ end }} + {{ partial "helpers/section-title.html" (dict "title" .Title "page" $page) }}
{{ $paginator := .Paginate .Data.Pages }} {{ range $paginator.Pages }} diff --git a/themes/capro-tw/layouts/index.html b/themes/capro-tw/layouts/index.html index 4528f81c..be2162a4 100644 --- a/themes/capro-tw/layouts/index.html +++ b/themes/capro-tw/layouts/index.html @@ -1,14 +1,5 @@ {{ define "main" }} - {{ partial "sections/about.html" . }} - {{ partial "sections/feature.html" . }} - {{ partial "sections/news.html" . }} - {{ partial "sections/service.html" . }} - {{ partial "sections/cta.html" . }} - {{ partial "sections/skill.html" . }} - {{ partial "sections/portfolio.html" . }} - {{ partial "sections/funfacts.html" . }} - {{ partial "sections/team.html" . }} - {{ partial "sections/pricing.html" . }} - {{ partial "sections/testimonial.html" . }} + {{ partial "sections/help.html" . }} + {{ partial "sections/people.html" . }} {{ partial "sections/contact.html" . }} {{ end }} diff --git a/themes/capro-tw/layouts/partials/footer/footer.html b/themes/capro-tw/layouts/partials/footer/footer.html index c68e5e6a..1fd49891 100644 --- a/themes/capro-tw/layouts/partials/footer/footer.html +++ b/themes/capro-tw/layouts/partials/footer/footer.html @@ -17,6 +17,13 @@ {{ end }}
+ {{/* The team is not in the main nav; keep /team/ reachable site-wide. */}} + {{ with resources.GetMatch site.Params.logo }} {{ site.Title }} diff --git a/themes/capro-tw/layouts/partials/footer/scripts.html b/themes/capro-tw/layouts/partials/footer/scripts.html index 2223c396..f853f7b8 100644 --- a/themes/capro-tw/layouts/partials/footer/scripts.html +++ b/themes/capro-tw/layouts/partials/footer/scripts.html @@ -1,11 +1,5 @@ {{/* Site JS: concat → minify → fingerprint */}} -{{ $js := slice - (resources.Get "js/scroll-reveal.js") - (resources.Get "js/counter.js") - | resources.Concat "capro.js" - | minify - | fingerprint -}} +{{ $js := resources.Get "js/scroll-reveal.js" | minify | fingerprint }} {{/* Alpine.js */}} diff --git a/themes/capro-tw/layouts/partials/helpers/link.html b/themes/capro-tw/layouts/partials/helpers/link.html new file mode 100644 index 00000000..2a2eec6d --- /dev/null +++ b/themes/capro-tw/layouts/partials/helpers/link.html @@ -0,0 +1,13 @@ +{{- /* Resolves a configured link for the current page and language. + "#anchor" -> home-page anchor (prefixed when not on the home page) + "/path/" -> language-aware internal URL + otherwise -> left untouched (external URLs, mailto:, ...) */ -}} +{{- $url := .url -}} +{{- $page := .page -}} +{{- if hasPrefix $url "#" -}} + {{- if $page.IsHome -}}{{ $url }}{{- else -}}{{ print $page.Site.Home.RelPermalink $url }}{{- end -}} +{{- else if hasPrefix $url "/" -}} + {{- $url | relLangURL -}} +{{- else -}} + {{- $url -}} +{{- end -}} diff --git a/themes/capro-tw/layouts/partials/helpers/section-intro.html b/themes/capro-tw/layouts/partials/helpers/section-intro.html new file mode 100644 index 00000000..c459feab --- /dev/null +++ b/themes/capro-tw/layouts/partials/helpers/section-intro.html @@ -0,0 +1,4 @@ +{{- /* Centred lead paragraph under a section heading. */ -}} +{{- with . -}} +
{{ . }}
+{{- end -}} diff --git a/themes/capro-tw/layouts/partials/helpers/section-title.html b/themes/capro-tw/layouts/partials/helpers/section-title.html new file mode 100644 index 00000000..69702332 --- /dev/null +++ b/themes/capro-tw/layouts/partials/helpers/section-title.html @@ -0,0 +1,38 @@ +{{- /* Section heading: first word plain, remainder accented. + + Takes either a plain title string, or a dict {title, page}. When a page + is supplied and has no

yet (list pages have no hero), the first + section title on that page is promoted to

so every page has one. + The home page gets its

from the banner. + + The two levels are written out in full rather than interpolating the tag + name: Go's html/template cannot compute an output context for a dynamic + element name and silently renders nothing. */ -}} +{{- $title := . -}} +{{- $page := false -}} +{{- if reflect.IsMap . -}} + {{- $title = .title -}} + {{- $page = .page -}} +{{- end -}} +{{- with $title -}} +{{- $promote := false -}} +{{- if and $page (not $page.IsHome) -}} + {{- if not ($page.Scratch.Get "sectionH1Used") -}} + {{- $promote = true -}} + {{- $page.Scratch.Set "sectionH1Used" true -}} + {{- end -}} +{{- end -}} +{{- if $page -}}{{- $page.Scratch.Set "itemLevel" (cond $promote 2 3) -}}{{- end -}} +{{- $words := split . " " -}} +{{- $head := index $words 0 -}} +{{- $rest := "" -}} +{{- if gt (len $words) 1 -}}{{- $rest = delimit (after 1 $words) " " -}}{{- end -}} +
+ {{ if $promote -}} +

{{ $head | safeHTML }}{{ with $rest }} {{ . | safeHTML }}{{ end }}

+ {{- else -}} +

{{ $head | safeHTML }}{{ with $rest }} {{ . | safeHTML }}{{ end }}

+ {{- end }} +
+
+{{- end -}} diff --git a/themes/capro-tw/layouts/partials/nav.html b/themes/capro-tw/layouts/partials/nav.html index a2947fe5..8f06bc9f 100644 --- a/themes/capro-tw/layouts/partials/nav.html +++ b/themes/capro-tw/layouts/partials/nav.html @@ -1,6 +1,10 @@ -