aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2023-02-19 14:08:33 +0100
committerivarlovlie <git@ivarlovlie.no>2023-02-19 14:08:33 +0100
commit54bbc06bd84437c6b38e2f6c57060f21a8318720 (patch)
treea0f9beb425829e304cdf239709e7d23a13b0fcc8 /src
parent06ce8fbab52c5c25a67a1518f1888b083b5edde3 (diff)
downloadauroraklinikken.no-54bbc06bd84437c6b38e2f6c57060f21a8318720.tar.xz
auroraklinikken.no-54bbc06bd84437c6b38e2f6c57060f21a8318720.zip
.
Diffstat (limited to 'src')
-rw-r--r--src/app.html199
-rw-r--r--src/components/card-v4.svelte15
-rw-r--r--src/global.d.ts16
-rw-r--r--src/hooks.server.ts62
-rw-r--r--src/i18n/en/index.ts8
-rw-r--r--src/i18n/formatters.ts11
-rw-r--r--src/i18n/nb/index.ts8
-rw-r--r--src/index.test.ts6
-rw-r--r--src/lib/sanity-client.ts14
-rw-r--r--src/lib/utils.ts32
-rw-r--r--src/params/lang.ts8
-rw-r--r--src/routes/+layout.server.ts8
-rw-r--r--src/routes/+layout.svelte3
-rw-r--r--src/routes/+layout.ts22
-rw-r--r--src/routes/[lang=lang]/+page.server.ts54
-rw-r--r--src/routes/[lang=lang]/+page.svelte2
-rw-r--r--src/routes/[lang=lang]/+page.ts30
-rw-r--r--src/routes/[lang=lang]/sections/products.svelte17
18 files changed, 265 insertions, 250 deletions
diff --git a/src/app.html b/src/app.html
index ef0bfa1..68797f1 100644
--- a/src/app.html
+++ b/src/app.html
@@ -1,122 +1,121 @@
<!DOCTYPE html>
<html lang="%lang%">
-<head>
- <meta charset="utf-8" />
- <link rel="icon" href="%sveltekit.assets%/favicon.png" />
- <meta name="viewport" content="width=device-width, initial-scale=1" />
- <style>
- /* reset */
- *,
- *::after,
- *::before {
- box-sizing: border-box;
- }
-
- * {
- font: inherit;
- margin: 0;
- padding: 0;
- border: 0;
- }
-
- body {
- background-color: hsl(0, 0%, 100%);
- font-family: system-ui, sans-serif;
- color: hsl(230, 7%, 23%);
- font-size: 1rem;
- }
-
- h1,
- h2,
- h3,
- h4 {
- line-height: 1.2;
- color: hsl(230, 13%, 9%);
- font-weight: 700;
- }
-
- h1 {
- font-size: 2.0736rem;
- }
-
- h2 {
- font-size: 1.728rem;
- }
+ <head>
+ <meta charset="utf-8" />
+ <link rel="icon" href="%sveltekit.assets%/favicon.png" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <style>
+ /* reset */
+ *,
+ *::after,
+ *::before {
+ box-sizing: border-box;
+ }
- h3 {
- font-size: 1.25rem;
- }
+ * {
+ font: inherit;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ }
- h4 {
- font-size: 1.2rem;
- }
+ body {
+ background-color: hsl(0, 0%, 100%);
+ font-family: system-ui, sans-serif;
+ color: hsl(230, 7%, 23%);
+ font-size: 1rem;
+ }
- ol,
- ul,
- menu {
- list-style: none;
- }
+ h1,
+ h2,
+ h3,
+ h4 {
+ line-height: 1.2;
+ color: hsl(230, 13%, 9%);
+ font-weight: 700;
+ }
- button,
- input,
- textarea,
- select {
- background-color: transparent;
- border-radius: 0;
- color: inherit;
- line-height: inherit;
- appearance: none;
- }
+ h1 {
+ font-size: 2.0736rem;
+ }
- textarea {
- resize: vertical;
- overflow: auto;
- vertical-align: top;
- }
+ h2 {
+ font-size: 1.728rem;
+ }
- a {
- color: hsl(250, 84%, 54%);
- }
+ h3 {
+ font-size: 1.25rem;
+ }
- table {
- border-collapse: collapse;
- border-spacing: 0;
- }
+ h4 {
+ font-size: 1.2rem;
+ }
- img,
- video,
- svg {
- display: block;
- max-width: 100%;
- }
+ ol,
+ ul,
+ menu {
+ list-style: none;
+ }
- @media (min-width: 64rem) {
- body {
- font-size: 1.25rem;
+ button,
+ input,
+ textarea,
+ select {
+ background-color: transparent;
+ border-radius: 0;
+ color: inherit;
+ line-height: inherit;
+ appearance: none;
}
- h1 {
- font-size: 3.051rem;
+ textarea {
+ resize: vertical;
+ overflow: auto;
+ vertical-align: top;
}
- h2 {
- font-size: 2.44rem;
+ a {
+ color: hsl(250, 84%, 54%);
}
- h3 {
- font-size: 1.75rem;
+ table {
+ border-collapse: collapse;
+ border-spacing: 0;
}
- h4 {
- font-size: 1.5625rem;
+ img,
+ video,
+ svg {
+ display: block;
+ max-width: 100%;
}
- }
- </style>
- %sveltekit.head%
-</head>
-<body>
- <div>%sveltekit.body%</div>
-</body>
+ @media (min-width: 64rem) {
+ body {
+ font-size: 1.25rem;
+ }
+
+ h1 {
+ font-size: 3.051rem;
+ }
+
+ h2 {
+ font-size: 2.44rem;
+ }
+
+ h3 {
+ font-size: 1.75rem;
+ }
+
+ h4 {
+ font-size: 1.5625rem;
+ }
+ }
+ </style>
+ %sveltekit.head%
+ </head>
-</html> \ No newline at end of file
+ <body>
+ <div>%sveltekit.body%</div>
+ </body>
+</html>
diff --git a/src/components/card-v4.svelte b/src/components/card-v4.svelte
index d067357..ff35492 100644
--- a/src/components/card-v4.svelte
+++ b/src/components/card-v4.svelte
@@ -1,13 +1,20 @@
<script lang="ts">
- export let title;
- export let description;
+ import { PortableText } from "@portabletext/svelte";
+ import type { InputValue } from "@portabletext/svelte/ptTypes";
+
+ export let title: string | undefined;
+ export let description: string | undefined | InputValue;
</script>
<div class="card">
<div class="p-6">
- <h3 class="mt-0">I have a dream</h3>
+ <h3 class="mt-0">{title}</h3>
<p class="text-contrast-medium mt-3 mx-0 mb-4">
- Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quia minus culpa commodi.
+ {#if typeof description === "string"}
+ {description}
+ {:else}
+ <PortableText value={description} />
+ {/if}
</p>
<div class="flex flex-wrap gap-3">
<a href="#0" class="btn btn--subtle">Learn more</a>
diff --git a/src/global.d.ts b/src/global.d.ts
index e49922a..075c69d 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -1,13 +1,13 @@
/// <reference types="@sveltejs/kit" />
-type Locales = import('$i18n/i18n-types').Locales
-type TranslationFunctions = import('$i18n/i18n-types').TranslationFunctions
+type Locales = import("$i18n/i18n-types").Locales;
+type TranslationFunctions = import("$i18n/i18n-types").TranslationFunctions;
declare namespace App {
- interface Locals {
- locale: Locales
- LL: TranslationFunctions
- }
+ interface Locals {
+ locale: Locales;
+ LL: TranslationFunctions;
+ }
- // interface Platform { }
-} \ No newline at end of file
+ // interface Platform { }
+}
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index ddd9342..1c8c988 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -1,43 +1,41 @@
-import { detectLocale, i18n, isLocale } from '$i18n/i18n-util'
-import { loadAllLocales } from '$i18n/i18n-util.sync'
-import type { Handle, RequestEvent } from '@sveltejs/kit'
-import { initAcceptLanguageHeaderDetector } from 'typesafe-i18n/detectors'
+import { detectLocale, i18n, isLocale } from "$i18n/i18n-util";
+import { loadAllLocales } from "$i18n/i18n-util.sync";
+import type { Handle, RequestEvent } from "@sveltejs/kit";
+import { initAcceptLanguageHeaderDetector } from "typesafe-i18n/detectors";
-loadAllLocales()
-const L = i18n()
+loadAllLocales();
+const L = i18n();
export const handle: Handle = async ({ event, resolve }) => {
- // read language slug
- const [, lang] = event.url.pathname.split('/')
+ // read language slug
+ const [, lang] = event.url.pathname.split("/");
- // redirect to base locale if no locale slug was found
- if (!lang) {
- const locale = getPreferredLocale(event)
+ // redirect to base locale if no locale slug was found
+ if (!lang) {
+ const locale = getPreferredLocale(event);
- return new Response(null, {
- status: 302,
- headers: { Location: `/${locale}` },
- })
- }
+ return new Response(null, {
+ status: 302,
+ headers: { Location: `/${locale}` },
+ });
+ }
- // if slug is not a locale, use base locale (e.g. api endpoints)
- const locale = isLocale(lang) ? (lang as Locales) : getPreferredLocale(event)
- const LL = L[locale]
+ // if slug is not a locale, use base locale (e.g. api endpoints)
+ const locale = isLocale(lang) ? (lang as Locales) : getPreferredLocale(event);
+ const LL = L[locale];
- // bind locale and translation functions to current request
- event.locals.locale = locale
- event.locals.LL = LL
+ // bind locale and translation functions to current request
+ event.locals.locale = locale;
+ event.locals.LL = LL;
- console.info(LL.log({ fileName: 'hooks.server.ts' }))
-
- // replace html lang attribute with correct language
- return resolve(event, { transformPageChunk: ({ html }) => html.replace('%lang%', locale) })
-}
+ // replace html lang attribute with correct language
+ return resolve(event, { transformPageChunk: ({ html }) => html.replace("%lang%", locale) });
+};
const getPreferredLocale = ({ request }: RequestEvent) => {
- // detect the preferred language the user has configured in his browser
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
- const acceptLanguageDetector = initAcceptLanguageHeaderDetector(request)
+ // detect the preferred language the user has configured in his browser
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
+ const acceptLanguageDetector = initAcceptLanguageHeaderDetector(request);
- return detectLocale(acceptLanguageDetector)
-} \ No newline at end of file
+ return detectLocale(acceptLanguageDetector);
+};
diff --git a/src/i18n/en/index.ts b/src/i18n/en/index.ts
index 796f4a5..a6b79c2 100644
--- a/src/i18n/en/index.ts
+++ b/src/i18n/en/index.ts
@@ -1,13 +1,13 @@
-import type { BaseTranslation } from '../i18n-types'
+import type { BaseTranslation } from "../i18n-types";
const en = {
contact: {
title: "Contact us",
addressTitle: "Address",
emailTitle: "Email",
- phoneTitle: "Phone"
+ phoneTitle: "Phone",
},
homeTitle: "Home",
-} satisfies BaseTranslation
+} satisfies BaseTranslation;
-export default en
+export default en;
diff --git a/src/i18n/formatters.ts b/src/i18n/formatters.ts
index 78734f9..b1fd5a3 100644
--- a/src/i18n/formatters.ts
+++ b/src/i18n/formatters.ts
@@ -1,11 +1,10 @@
-import type { FormattersInitializer } from 'typesafe-i18n'
-import type { Locales, Formatters } from './i18n-types'
+import type { FormattersInitializer } from "typesafe-i18n";
+import type { Locales, Formatters } from "./i18n-types";
export const initFormatters: FormattersInitializer<Locales, Formatters> = (locale: Locales) => {
-
const formatters: Formatters = {
// add your formatter functions here
- }
+ };
- return formatters
-}
+ return formatters;
+};
diff --git a/src/i18n/nb/index.ts b/src/i18n/nb/index.ts
index 9e13fba..5206b07 100644
--- a/src/i18n/nb/index.ts
+++ b/src/i18n/nb/index.ts
@@ -1,13 +1,13 @@
-import type { Translation } from '../i18n-types'
+import type { Translation } from "../i18n-types";
const nb = {
contact: {
title: "Kontakt oss",
addressTitle: "Adresse",
emailTitle: "E-postadresse",
- phoneTitle: "Telefon"
+ phoneTitle: "Telefon",
},
homeTitle: "Hjem",
-} satisfies Translation
+} satisfies Translation;
-export default nb
+export default nb;
diff --git a/src/index.test.ts b/src/index.test.ts
index e07cbbd..808401e 100644
--- a/src/index.test.ts
+++ b/src/index.test.ts
@@ -1,7 +1,7 @@
-import { describe, it, expect } from 'vitest';
+import { describe, it, expect } from "vitest";
-describe('sum test', () => {
- it('adds 1 + 2 to equal 3', () => {
+describe("sum test", () => {
+ it("adds 1 + 2 to equal 3", () => {
expect(1 + 2).toBe(3);
});
});
diff --git a/src/lib/sanity-client.ts b/src/lib/sanity-client.ts
index 96253ca..7aa868b 100644
--- a/src/lib/sanity-client.ts
+++ b/src/lib/sanity-client.ts
@@ -1,9 +1,9 @@
import { env } from "$env/dynamic/private";
-import createSanityClient from "@sanity/client";
+import { createClient } from "@sanity/client";
-export const sanity = createSanityClient({
- projectId: env.SANITY_STUDIO_API_PROJECT_ID,
- dataset: env.SANITY_STUDIO_API_DATASET,
- apiVersion: "2022-03-24",
- useCdn: true,
-}); \ No newline at end of file
+export const sanity = createClient({
+ projectId: env.SANITY_STUDIO_API_PROJECT_ID,
+ dataset: env.SANITY_STUDIO_API_DATASET,
+ apiVersion: "2022-03-24",
+ useCdn: true,
+});
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
index 4ec8b01..f7c040d 100644
--- a/src/lib/utils.ts
+++ b/src/lib/utils.ts
@@ -6,22 +6,22 @@
// Otherwise (default) the URL relative to the base is returned.
// e.g. https://mywebsite.com/en/blog/article-1 => /de/blog/article-1
export const replaceLocaleInUrl = (url: URL, locale: string, full = false): string => {
- const [, , ...rest] = url.pathname.split('/')
- const new_pathname = `/${[locale, ...rest].join('/')}`
- if (!full) {
- return `${new_pathname}${url.search}`
- }
- const newUrl = new URL(url.toString())
- newUrl.pathname = new_pathname
- return newUrl.toString()
-}
+ const [, , ...rest] = url.pathname.split("/");
+ const new_pathname = `/${[locale, ...rest].join("/")}`;
+ if (!full) {
+ return `${new_pathname}${url.search}`;
+ }
+ const newUrl = new URL(url.toString());
+ newUrl.pathname = new_pathname;
+ return newUrl.toString();
+};
export function fromLocalizedString(localizedString: string | object, locale: Locales) {
- if (typeof localizedString === "string") return localizedString;
- // @ts-ignore
- if (localizedString[locale]) return localizedString[locale];
- // @ts-ignore
- if (localizedString["nb"]) return localizedString["nb"];
- // @ts-ignore
- if (localizedString["en"]) return localizedString["en"];
+ if (typeof localizedString === "string") return localizedString;
+ // @ts-ignore
+ if (localizedString[locale]) return localizedString[locale];
+ // @ts-ignore
+ if (localizedString["nb"]) return localizedString["nb"];
+ // @ts-ignore
+ if (localizedString["en"]) return localizedString["en"];
}
diff --git a/src/params/lang.ts b/src/params/lang.ts
index 5f0b857..5f7e2a2 100644
--- a/src/params/lang.ts
+++ b/src/params/lang.ts
@@ -1,7 +1,7 @@
-import type { ParamMatcher } from '@sveltejs/kit'
-import { isLocale } from '$i18n/i18n-util'
+import type { ParamMatcher } from "@sveltejs/kit";
+import { isLocale } from "$i18n/i18n-util";
// only accept valid languages as a segment in the URL
export const match: ParamMatcher = (param) => {
- return isLocale(param)
-} \ No newline at end of file
+ return isLocale(param);
+};
diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts
index fc087d8..0eef9d3 100644
--- a/src/routes/+layout.server.ts
+++ b/src/routes/+layout.server.ts
@@ -1,6 +1,6 @@
-import type { LayoutServerLoad } from './$types'
+import type { LayoutServerLoad } from "./$types";
export const load: LayoutServerLoad = ({ locals: { locale, LL } }) => {
- // pass locale information from "server-context" to "shared server + client context"
- return { locale }
-}
+ // pass locale information from "server-context" to "shared server + client context"
+ return { locale };
+};
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index af29844..97aa8cf 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -1,12 +1,9 @@
<script lang="ts">
import { page } from "$app/stores";
import "../app.postcss";
- import type { LayoutData } from "./$types";
import { locales, baseLocale } from "$i18n/i18n-util";
import { replaceLocaleInUrl } from "$lib/utils";
import Header from "./parts/header.svelte";
-
- export let data: LayoutData;
</script>
<svelte:head>
diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts
index 5a78ab1..ab3b2cc 100644
--- a/src/routes/+layout.ts
+++ b/src/routes/+layout.ts
@@ -1,14 +1,14 @@
-import type { LayoutLoad } from './$types'
-import { loadLocaleAsync } from '$i18n/i18n-util.async'
-import { setLocale } from '$i18n/i18n-svelte'
+import type { LayoutLoad } from "./$types";
+import { loadLocaleAsync } from "$i18n/i18n-util.async";
+import { setLocale } from "$i18n/i18n-svelte";
export const load = (async ({ data: { locale } }) => {
- // load dictionary into memory
- await loadLocaleAsync(locale)
+ // load dictionary into memory
+ await loadLocaleAsync(locale);
- // if you need to output a localized string in a `load` function,
- // you always need to call `setLocale` right before you access the `LL` store
- setLocale(locale)
- // pass locale to the "rendering context"
- return { locale }
-}) satisfies LayoutLoad<{ locale: Locales }>; \ No newline at end of file
+ // if you need to output a localized string in a `load` function,
+ // you always need to call `setLocale` right before you access the `LL` store
+ setLocale(locale);
+ // pass locale to the "rendering context"
+ return { locale };
+}) satisfies LayoutLoad<{ locale: Locales }>;
diff --git a/src/routes/[lang=lang]/+page.server.ts b/src/routes/[lang=lang]/+page.server.ts
index a647cfe..c2284ee 100644
--- a/src/routes/[lang=lang]/+page.server.ts
+++ b/src/routes/[lang=lang]/+page.server.ts
@@ -1,29 +1,31 @@
-import { sanity } from '$lib/sanity-client';
-import type { PageServerLoad } from './$types';
+import { sanity } from "$lib/sanity-client";
+import type { PageServerLoad } from "./$types";
import groq from "groq";
-import type { ContactModel } from './sections/contact.svelte';
-import { fromLocalizedString } from '$lib/utils';
-import type { HeroModel } from './sections/hero.svelte';
-import type { DescriptionModel } from './sections/description.svelte';
+import type { ContactModel } from "./sections/contact.svelte";
+import { fromLocalizedString } from "$lib/utils";
+import type { HeroModel } from "./sections/hero.svelte";
+import type { DescriptionModel } from "./sections/description.svelte";
export const load = (async ({ locals }) => {
- const contactSection = await sanity.fetch(groq`*[_type == "contact"][0]`);
- const heroSection = await sanity.fetch(groq`*[_type == "hero"][0]`);
- const descriptionSection = await sanity.fetch(groq`*[_type == "description"][0]`);
- return {
- contact: {
- phone: fromLocalizedString(contactSection.phone, locals.locale),
- email: fromLocalizedString(contactSection.email, locals.locale),
- phoneHours: fromLocalizedString(contactSection.phoneHours, locals.locale),
- addressLines: contactSection.addressLines.map((el: string | object) => fromLocalizedString(el, locals.locale)),
- } as ContactModel,
- hero: {
- title: heroSection.title,
- content: heroSection.content
- } as HeroModel,
- description: {
- title: descriptionSection.title,
- content: descriptionSection.content
- } as DescriptionModel
- };
-}) satisfies PageServerLoad; \ No newline at end of file
+ const contactSection = await sanity.fetch(groq`*[_type == "contact"][0]`);
+ const heroSection = await sanity.fetch(groq`*[_type == "hero"][0]`);
+ const descriptionSection = await sanity.fetch(groq`*[_type == "description"][0]`);
+ const products = await sanity.fetch(groq`*[_type == "product"]`);
+ return {
+ contact: {
+ phone: fromLocalizedString(contactSection.phone, locals.locale),
+ email: fromLocalizedString(contactSection.email, locals.locale),
+ phoneHours: fromLocalizedString(contactSection.phoneHours, locals.locale),
+ addressLines: contactSection.addressLines.map((el: string | object) => fromLocalizedString(el, locals.locale)),
+ } as ContactModel,
+ hero: {
+ title: heroSection.title,
+ content: heroSection.content,
+ } as HeroModel,
+ description: {
+ title: descriptionSection.title,
+ content: descriptionSection.content,
+ } as DescriptionModel,
+ products: products
+ };
+}) satisfies PageServerLoad;
diff --git a/src/routes/[lang=lang]/+page.svelte b/src/routes/[lang=lang]/+page.svelte
index 325f085..f2028c6 100644
--- a/src/routes/[lang=lang]/+page.svelte
+++ b/src/routes/[lang=lang]/+page.svelte
@@ -12,4 +12,4 @@
<Hero model={data.hero} />
<Description model={data.description} />
<Contact model={data.contact} />
-<Products model={data.products} /> \ No newline at end of file
+<Products model={data.products} />
diff --git a/src/routes/[lang=lang]/+page.ts b/src/routes/[lang=lang]/+page.ts
index 1ef0b57..fa95472 100644
--- a/src/routes/[lang=lang]/+page.ts
+++ b/src/routes/[lang=lang]/+page.ts
@@ -1,18 +1,18 @@
-import type { PageLoad } from './$types';
-import LL, { setLocale } from '$i18n/i18n-svelte'
-import { get } from 'svelte/store'
+import type { PageLoad } from "./$types";
+import LL, { setLocale } from "$i18n/i18n-svelte";
+import { get } from "svelte/store";
export const load = (async ({ parent, data }) => {
- // wait for `+layout.ts` to load dictionary and pass locale information
- const { locale } = await parent()
+ // wait for `+layout.ts` to load dictionary and pass locale information
+ const { locale } = await parent();
- // if you need to output a localized string in a `load` function,
- // you always need to call `setLocale` right before you access the `LL` store
- setLocale(locale)
- // get the translation functions value from the store
- const $LL = get(LL)
- return {
- title: $LL.homeTitle(),
- ...data
- }
-}) satisfies PageLoad; \ No newline at end of file
+ // if you need to output a localized string in a `load` function,
+ // you always need to call `setLocale` right before you access the `LL` store
+ setLocale(locale);
+ // get the translation functions value from the store
+ const $LL = get(LL);
+ return {
+ title: $LL.homeTitle(),
+ ...data,
+ };
+}) satisfies PageLoad;
diff --git a/src/routes/[lang=lang]/sections/products.svelte b/src/routes/[lang=lang]/sections/products.svelte
index 4e10b6f..816e276 100644
--- a/src/routes/[lang=lang]/sections/products.svelte
+++ b/src/routes/[lang=lang]/sections/products.svelte
@@ -13,6 +13,8 @@
</script>
<script lang="ts">
+ import CardV4 from "$components/card-v4.svelte";
+
export let model: ProductsModel;
let visible = true;
@@ -24,5 +26,16 @@
</script>
{#if visible}
-
-{/if} \ No newline at end of file
+ <div class="wrapper">
+ {#each model.products as product}
+ <CardV4 description={product.description} title={product.title} />
+ {/each}
+ </div>
+{/if}
+
+<style lang="postcss">
+ .wrapper {
+ display: grid;
+ grid-template-columns: repeat(50%);
+ }
+</style>