/*
Theme Name: Karivarah
Theme URI: https://karivarah.com
Description: Child theme of Hello Elementor for Karivarah. Holds the small amount of custom behaviour the site needs, so none of it lives in a plugin or a snippet manager.
Author: Karivarah
Template: hello-elementor
Version: 1.0.0
Text Domain: karivarah
*/

/* ===========================================================================
   Contents

   Sections in the order they appear. Search for a section's opening words
   to jump to it; line numbers are left out because they go stale.

   Foundations      The typeface · Tokens · The parent theme's button reset
                    · Type, site wide
                    · Links, site wide · Elevation · Icons · No touch highlight
   Components       Buttons · A deactivated call to action · The banner · The
                    caret · The soft grey lines · The round button · The
                    lightbox · Tables · Notifications · Form fields · The
                    dropdown a writer can put in an article
   Header, footer   Header · Main navigation · Search · Footer · Announcement
                    strip · Footer columns · Badge carousel · Menu overlay ·
                    Shop dropdown · Shop panel geometry
   Shop             Shop page · Category, craft and collection pages · Product
                    page · The full size gallery · Cart · Order confirmation
   Pages            Contact page · FAQ page · Blog archive · Blog post · 404 ·
                    Legal documents · About us · The gallery · The home page ·
                    The content hub
   Flows            Signing in without a password · The card against its
                    frames · The waiting list · The account area · Angre
                    kjøpet her (returns)

   Two kinds of rule break the order and are marked where they sit:
   "Site-wide" rules inside a page's block that size every button, field or
   arrow on small screens, and rules placed late on purpose to outrank an
   earlier one, whose comment says which.
   ======================================================================== */

/* ---------------------------------------------------------------------------
   The typeface. Fixel Text, self-hosted, Regular 400 and SemiBold 600.

   Two files and nothing else: the design uses no italic and no third weight.
   The family name has to be `Fixel Text` rather than `Fixel Text Regular`. The
   typographic family is name ID 16 and the full name is name ID 1, and naming
   the full name leaves the 600 with nothing to bind to.

   `font-display: swap` matches what Elementor's kit already sets, so a slow
   file shows the fallback rather than nothing.

   No `unicode-range` here, deliberately. It would save a download only on a
   page with no Latin text, and there is no such page on this site, while a
   character left outside the range falls back to the system font silently.
   The file carries 1,196 glyphs and every character the copy uses.
   ------------------------------------------------------------------------ */

@font-face {
	font-family: 'Fixel Text';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('assets/fonts/FixelText-Regular.woff2') format('woff2');
}

@font-face {
	font-family: 'Fixel Text';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('assets/fonts/FixelText-SemiBold.woff2') format('woff2');
}

/* ---------------------------------------------------------------------------
   Tabular figures, where digits are meant to line up under each other.

   Fixel carries `tnum`, which Poppins did not, so this rule only does anything
   because of the typeface change: revert the font and it goes quiet rather than
   breaking. Scoped rather than global, because `1` grows 55% under tnum, from
   386 units to 600, and running prose set in tabular figures reads wrong.

   Prices, so the decimal point sits still down a column of cards, and the
   product details rows, which are read down rather than across. The invoice and
   the withdrawal form get the same thing by a different route: dompdf has no
   GSUB, so the feature is frozen into the two PDF font files instead.

   The property inherits, so each selector below is the container that holds the
   money rather than the element printing it. The second group was missed on the
   first pass, 14.10.2026: a summary read down a column is the strongest case
   there is for this, and it was the one place without it.
   ------------------------------------------------------------------------ */

.kv-price,
.kv-pdp__price,
.kv-cartrow__price,
.kv-pacc__body,

/* The cart summary, the same rows in the cart pop-up's foot, and the returns
   panel, which builds its own rows into one of these. */
.kv-sum__rows,
.kv-sum__row,

/* How much is left to free shipping, above both summaries. */
.kv-ship__text,

/* An order: the line prices, its totals, the list of orders, and the invoice
   the account falls back to when the PDF plugin is not there. */
.kv-oitem__money,
.kv-vieworder__summary,
.kv-order__sum,
.kv-invoice__lines,

/* The two ends of the shop's price filter. */
.kv-prange__nums {
	font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
   Tokens, transcribed from the Figma style guide's own variables, node 1:135.
   Elementor's global kit carries the same values for anything edited in the
   builder; these are for the theme's own markup, so there is one source for
   both. The Figma path is in the comment beside any token whose name differs.

   Nothing below this block states a colour, a type size or a shadow as a
   literal. If a value is missing here it is missing from the style guide, which
   is a question for the design rather than a number to invent.
   ------------------------------------------------------------------------ */

:root {
	/* Text */
	--kv-text: #231F20;			/* Text/Primary */
	--kv-text-2: #6A6A6A;			/* Text/Secondary */
	--kv-text-disabled: #BEBEBE;		/* Text/Disabled */

	/* Primary. The 4p to 50p steps are Primary/Shades, used as washes */
	--kv-primary: #CB5827;			/* Primary/Main */
	--kv-primary-dark: #AE3E1C;		/* Primary/Dark, the pressed state */
	--kv-primary-light: #DF8958;		/* Primary/Light, the hover stroke */
	--kv-primary-4: rgba(203, 88, 39, 0.04);
	--kv-primary-6: rgba(203, 88, 39, 0.06);
	--kv-primary-8: rgba(203, 88, 39, 0.08);
	--kv-primary-12: rgba(203, 88, 39, 0.12);
	--kv-primary-14: rgba(203, 88, 39, 0.14);
	--kv-primary-16: rgba(203, 88, 39, 0.16);
	--kv-primary-24: rgba(203, 88, 39, 0.24);
	--kv-primary-30: rgba(203, 88, 39, 0.3);
	--kv-primary-50: rgba(203, 88, 39, 0.5);

	/* Secondary */
	--kv-secondary: #F6D46B;		/* Secondary/Main */
	--kv-secondary-dark: #D3AF4E;		/* Secondary/Dark */
	--kv-secondary-light: #F9E28F;		/* Secondary/Light */
	--kv-secondary-30: rgba(246, 212, 107, 0.3);

	/* States */
	--kv-error: #EF4721;			/* Error/Main */
	--kv-error-dark: #CD2B18;
	--kv-error-light: #F57F56;
	--kv-warning: #FFD101;			/* Warning/Main */
	--kv-warning-dark: #DBAA00;
	--kv-warning-light: #FFDC3F;
	--kv-info: #0ACEFF;			/* Info/Main */
	--kv-info-dark: #07A1DB;
	--kv-info-light: #47E7FF;
	--kv-success: #4BB543;			/* Success/Main */
	--kv-success-dark: #309B32;
	--kv-success-light: #7ED26F;
	--kv-success-text: #368230;		/* not in the style guide: Success/Main as text on white is 2.6:1, this is 4.7 */

	/* Greys, 100 lightest to 900 darkest */
	--kv-grey-100: #FBFAF9;
	--kv-grey-200: #F8F7F6;
	--kv-grey-300: #F6F4F3;
	--kv-grey-400: #F2EFED;
	--kv-grey-500: #EEEAE8;
	--kv-grey-600: #E9E4E2;
	--kv-grey-700: #E5DFDC;
	--kv-grey-800: #E1DAD6;
	--kv-grey-900: #DCD4D0;
	--kv-grey-primary-400: #F2F1EE;		/* Grey Primary/400, a warmer 400 */
	--kv-grey-flat-600: #EAEAEA;		/* Gray/600, neutral, not the warm Grey/600 */
	--kv-black-200: #8C8C8C;		/* black/200 */
	--kv-black-350: #4B4B4B;		/* black/350 */

	/* Surfaces */
	--kv-paper: #FFFFFF;			/* Backround/Paper */
	--kv-page: #FEFBFC;			/* Backround/Page */
	--kv-surface: #F9F9F9;			/* Backround/Default */
	--kv-white: #FFFFFF;			/* White/white */
	--kv-overlay-white-60: rgba(255, 255, 255, 0.6);
	--kv-overlay-white-90: rgba(255, 255, 255, 0.9);

	/* Type. Fixel Text throughout, Regular 400 and SemiBold 600. The ladder is one
	   scale and the weight is chosen separately, so each step carries a size and
	   a line height and nothing else. Raleway is on three style guide variables
	   and on nothing in the design, so it is not loaded. */
	--kv-font: 'Fixel Text', sans-serif;
	--kv-weight: 400;
	--kv-weight-semibold: 600;

	--kv-fs-h1: 48px;	--kv-lh-h1: 64px;
	--kv-fs-h2: 40px;	--kv-lh-h2: 56px;
	--kv-fs-h3: 36px;	--kv-lh-h3: 48px;
	--kv-fs-h4: 30px;	--kv-lh-h4: 40px;
	--kv-fs-h5: 24px;	--kv-lh-h5: 32px;
	--kv-fs-h6: 20px;	--kv-lh-h6: 28px;
	--kv-fs-sub1: 18px;	--kv-lh-sub1: 24px;
	--kv-fs-sub2: 16px;	--kv-lh-sub2: 24px;
	--kv-fs-body1: 16px;	--kv-lh-body1: 24px;
	--kv-fs-body2: 14px;	--kv-lh-body2: 20px;
	--kv-fs-caption: 12px;	--kv-lh-caption: 16px;
	--kv-fs-overline: 12px;	--kv-lh-overline: 16px;

	/* Buttons, three sizes, nodes 1:857 and 1:876. Each size sets its own
	   padding, radius, type step, stroke and icon gap. */
	--kv-btn-pad-lg: 16px 24px;	--kv-btn-radius-lg: 16px;	--kv-btn-stroke-lg: 1.5px;	--kv-btn-gap-lg: 8px;
	--kv-btn-pad-md: 12px 20px;	--kv-btn-radius-md: 12px;	--kv-btn-stroke-md: 1.2px;	--kv-btn-gap-md: 6px;
	--kv-btn-pad-sm: 12px 16px;	--kv-btn-radius-sm: 10px;	--kv-btn-stroke-sm: 1px;	--kv-btn-gap-sm: 4px;

	--kv-gutter: 152px;
	--kv-radius: 12px;

	/* The split banner: words one side, picture the other, running the full
	   width of the screen. Three heights, because the frames draw three: the
	   desktop one, the picture's height once the two halves stack, and the
	   phone's. A page that needs a taller banner sets `--kv-banner-h` on its
	   own element and inherits the other two. */
	--kv-banner-h: 480px;
	--kv-banner-h-md: 320px;
	--kv-banner-h-sm: 240px;
	--kv-banner-pad-y: 48px;

	/* Elevation, the style guide's six steps plus the coloured one that sits
	   under a primary button on hover. Figma gives blur and spread, and the
	   alpha is inside the effect colour: #9E9E9E1F is 12%. */
	--kv-elevation-1: 0 1px 2px rgba(158, 158, 158, 0.12);
	--kv-elevation-2: 0 8px 16px rgba(158, 158, 158, 0.06);
	--kv-elevation-3: 0 12px 24px -4px rgba(158, 158, 158, 0.12);
	--kv-elevation-4: 0 16px 32px -4px rgba(158, 158, 158, 0.12);
	--kv-elevation-5: 0 20px 40px -4px rgba(158, 158, 158, 0.12);
	--kv-elevation-6: 0 24px 48px rgba(158, 158, 158, 0.2);
	--kv-elevation-primary: 0 12px 20px var(--kv-primary-24);
}

@media (max-width: 1024px) { :root { --kv-gutter: 80px; } }
@media (max-width: 767px)  { :root { --kv-gutter: 16px; --kv-radius: 10px; } }

/* ---------------------------------------------------------------------------
   The parent theme's button reset

   Hello Elementor paints every bare <button> in #c36 with a 1px border of the
   same colour, and fills it magenta with white text on hover and on focus. It
   is placeholder styling, not a design decision, and it was showing up as a
   pink band over the cart's discount toggle, the pop-up's close cross and
   anything else that only declared how it looks at rest.

   Neutralised here, early, so every component further down this file still
   says how its own buttons behave.
   ------------------------------------------------------------------------ */

button, [type="button"], [type="submit"],
button:hover, button:focus,
[type="button"]:hover, [type="button"]:focus,
[type="submit"]:hover, [type="submit"]:focus {
	background-color: transparent;
	border-color: transparent;
	color: inherit;
}

/* ---------------------------------------------------------------------------
   Type, site wide

   The ladder lives in the tokens above and nowhere else. A component picks a
   step, it does not restate a number: `font-size: var(--kv-fs-h5)` rather than
   `24px`. Where a frame steps a heading down at a breakpoint, that step is
   still the component's own, because the step is drawn per screen and the
   style guide holds one ladder.

   Elementor's global kit sets h1 to h6 on the same SemiBold ladder, so the
   element defaults already match. These rules make the theme say it in its own
   voice rather than depend on a kit that is edited in the builder.

   `body` carries the family and the colour only. The kit sets the inherited
   line height to 1.8em and prose depends on that, so nothing here touches it.
   ------------------------------------------------------------------------ */

body.kv-site {
	font-family: var(--kv-font);
	color: var(--kv-text);
}

/* Form controls do not inherit type. One rule, so no component has to say it */
.kv-site input,
.kv-site button,
.kv-site select,
.kv-site textarea,
.kv-site optgroup {
	font-family: inherit;
}

/* The named steps, for markup that is not a heading element. Size and line
   height only: the weight is a separate choice, as in the style guide. */
/* Every step is scoped to `.kv-site`, which is on the body, so the selector
   weighs 0,2,0. The Elementor kit sets `h1` to `h6` as `.elementor-kit-6 h4`,
   which is 0,1,1 and beats a bare class: without the prefix this whole ladder
   loses on any heading element, which is exactly what it exists for. */
.kv-site .kv-h1 { font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1); }
.kv-site .kv-h2 { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
.kv-site .kv-h3 { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
.kv-site .kv-h4 { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
.kv-site .kv-h5 { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
.kv-site .kv-h6 { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
.kv-sub1 { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
.kv-sub2 { font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2); }
.kv-body1 { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-body2 { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
.kv-caption { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
.kv-overline { font-size: var(--kv-fs-overline); line-height: var(--kv-lh-overline); text-transform: uppercase; }
.kv-regular { font-weight: var(--kv-weight); }
.kv-semibold { font-weight: var(--kv-weight-semibold); }

/* The name at the head of a product name, wherever the name is drawn: the card,
   the product H1, the cart row and the cart pop-up. See
   karivarah_product_name_html(). */
.kv-pname { font-weight: var(--kv-weight-semibold); }

/* ---------------------------------------------------------------------------
   Links, site wide

   The kit paints every link orange. On this site that is wrong nearly
   everywhere: a link in the navigation, in a card, in the footer or on a
   product takes the colour of the text around it and turns orange on hover,
   which is what the frames draw and what two dozen components were each
   repeating for themselves.

   This rule is one class deep, the same as those components, and it sits above
   them in the file, so any component that genuinely differs still wins by
   being later. Prose is the exception and is handled by `.kv-prose` below.
   ------------------------------------------------------------------------ */

.kv-site a {
	color: inherit;
	text-decoration: none;
	transition: color .15s;
}

.kv-site a:hover,
.kv-site a:focus-visible {
	color: var(--kv-primary);
}

/* Prose: body copy a reader reads rather than navigates. A link inside it is
   underlined so it is visible without colour alone, and it takes the primary
   on hover like every other link. Used by the blog post, the legal documents,
   the term accordions and the product copy. */
.kv-prose a,
.kv-post__text a,
.kv-acc__body a,
/* And wherever a sentence beside a form carries one: the consent lines and
   the note under the overlay's heading. */
.kv-check label a,
.kv-del__note a,
.kv-overlay__lead a {
	text-decoration: underline;
	text-underline-position: from-font;
	text-decoration-skip-ink: none;
}

/* ---------------------------------------------------------------------------
   Elevation

   The six steps and the coloured one are tokens above. These classes exist so
   a shadow can be applied without naming a blur.
   ------------------------------------------------------------------------ */

.kv-elev-1 { box-shadow: var(--kv-elevation-1); }
.kv-elev-2 { box-shadow: var(--kv-elevation-2); }
.kv-elev-3 { box-shadow: var(--kv-elevation-3); }
.kv-elev-4 { box-shadow: var(--kv-elevation-4); }
.kv-elev-5 { box-shadow: var(--kv-elevation-5); }
.kv-elev-6 { box-shadow: var(--kv-elevation-6); }

/* ---------------------------------------------------------------------------
   Buttons, nodes 1:857 primary and 1:876 secondary

   Three sizes, large by default, and three states each. Taken off the
   components rather than inferred, because the hover had been guessed wrong:

   Primary   rest    fill Primary/Main, white words, no shadow
             hover   the same fill, and the coloured shadow appears under it
             active  fill Primary/Dark, shadow stays
   Secondary rest    1.5px stroke in Text/Primary, words in Text/Primary
             hover   stroke Primary/Light, words Primary/Main, still no fill
             active  the same, over a 4% primary wash

   So the primary does not darken on hover, it lifts; it darkens when pressed.
   The secondary's hover stroke is the light primary, not the main one.

   On a phone every button is resized by a rule in the cart's 767px block,
   marked "Site-wide". Search for that word to find it.
   ------------------------------------------------------------------------ */

.kv-btn {
	/* inline-flex, not flex: the frames size every button to its label, and a
	   block-level flex box fills whatever block it stands in, which is how the
	   hero, the about band and the reviews row came to carry buttons the full
	   width of the column.

	   Only the display changes. A button that is a flex item still stretches
	   where its row or column says to, which is what the cart summary and the
	   overlay want, so nothing that was meant to fill stops filling. */
	display: inline-flex;
	align-items: center; justify-content: center;
	gap: var(--kv-btn-gap-lg);
	padding: var(--kv-btn-pad-lg);
	border: 0; border-radius: var(--kv-btn-radius-lg);
	cursor: pointer;
	font-family: var(--kv-font);
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
	font-weight: var(--kv-weight);
	text-align: center; text-decoration: none;
	transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s;
}

.kv-btn--md {
	gap: var(--kv-btn-gap-md);
	padding: var(--kv-btn-pad-md);
	border-radius: var(--kv-btn-radius-md);
	font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2);
}

/* The About page drops to the medium button on a phone, nodes 2:23888 and
   2:23991, and keeps the large one above that, nodes 2:22633 and 2:25247. */
@media (max-width: 767px) {
	body.kv-site .kv-about .kv-btn {
		gap: var(--kv-btn-gap-md);
		padding: var(--kv-btn-pad-md);
		border-radius: var(--kv-btn-radius-md);
		font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2);
	}
	body.kv-site .kv-about .kv-btn--secondary {
		border-width: var(--kv-btn-stroke-md);
		padding: calc(12px - var(--kv-btn-stroke-md)) calc(20px - var(--kv-btn-stroke-md));
		min-height: calc(24px + var(--kv-lh-sub2));
	}
}

.kv-btn--sm {
	gap: var(--kv-btn-gap-sm);
	padding: var(--kv-btn-pad-sm);
	border-radius: var(--kv-btn-radius-sm);
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
}

.kv-btn--primary { background: var(--kv-primary); color: var(--kv-white); }
.kv-btn.kv-btn--primary { color: var(--kv-white); text-decoration: none; }
/* The lift belongs to the pointer, and it used to stay behind after one.
   Two reasons, and both of them end with a button that looks stuck:

   - A click leaves the button focused, and `:focus` was in this rule, so the
     lift outlived the pointer. `:focus-visible` is the browser saying this
     focus wants showing, which is the keyboard rather than the mouse, so the
     indicator is still there for anyone tabbing through and gone the moment a
     click ends.
   - A touch screen has no pointer to take away. It holds `:hover` on whatever
     was tapped until something else is tapped, so the hover half is asked for
     only where there is a pointer that can leave. */
.kv-btn.kv-btn--primary:focus-visible {
	background: var(--kv-primary);
	color: var(--kv-white);
	box-shadow: var(--kv-elevation-primary);
}
@media (hover: hover) {
	.kv-btn.kv-btn--primary:hover {
		background: var(--kv-primary);
		color: var(--kv-white);
		box-shadow: var(--kv-elevation-primary);
	}
}
.kv-btn.kv-btn--primary:active {
	background: var(--kv-primary-dark);
	color: var(--kv-white);
	box-shadow: var(--kv-elevation-primary);
}

.kv-btn--secondary { background: none; color: var(--kv-text); border: var(--kv-btn-stroke-lg) solid var(--kv-text); }
.kv-btn.kv-btn--secondary { color: var(--kv-text); text-decoration: none; }
.kv-btn.kv-btn--secondary:focus-visible {
	background: none;
	border-color: var(--kv-primary-light);
	color: var(--kv-primary);
}
@media (hover: hover) {
	.kv-btn.kv-btn--secondary:hover {
		background: none;
		border-color: var(--kv-primary-light);
		color: var(--kv-primary);
	}
}
.kv-btn.kv-btn--secondary:active {
	background: var(--kv-primary-4);
	border-color: var(--kv-primary-light);
	color: var(--kv-primary);
}

/* Buttons that are loading.

   WooCommerce marks a button `.loading` while its request runs (add to cart
   on a product page, in the theme's cart.php, and on WooCommerce's own
   listing buttons) and draws its icon-font glyph pinned .618em from the top,
   which sat 4.5px above the label's middle on the 56px button. The glyph is
   replaced by Phosphor's `circle-notch` in the brand white, as a mask so it
   takes the colour, centred on the button's height, turned by the theme's
   own keyframes (WooCommerce's `spin` lives in a stylesheet not every page
   loads). Four classes deep because WooCommerce's own selector weighs 0,3,2.
   Asked for by the client 15.10.2026. */
@keyframes kv-spin { to { transform: rotate(360deg); } }
body.kv-site .loading.loading.loading::after {
	content: "";
	font-family: inherit;
	position: absolute; top: 50%; right: 1em;
	width: 20px; height: 20px; margin-top: -10px;
	background: var(--kv-white);
	-webkit-mask: url("assets/icons/regular/circle-notch.svg") center / contain no-repeat;
	mask: url("assets/icons/regular/circle-notch.svg") center / contain no-repeat;
	line-height: 0; vertical-align: middle;
	animation: kv-spin 1s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
	body.kv-site .loading.loading.loading::after { animation-duration: 3s; }
}

.kv-btn--secondary.kv-btn--md { border-width: var(--kv-btn-stroke-md); }
.kv-btn--secondary.kv-btn--sm { border-width: var(--kv-btn-stroke-sm); }

/* The frames draw the stroke inside the button, node 2:22524: an outlined
   button stands the same 56 tall as a filled one beside it, not three more.
   The stroke comes out of the padding rather than being added to it, and a
   floor holds the height where a screen rounds the 1.5 to one device pixel
   and the padding has already given up its one and a half. */
.kv-btn--secondary { padding: calc(16px - var(--kv-btn-stroke-lg)) calc(24px - var(--kv-btn-stroke-lg)); }
.kv-btn--secondary.kv-btn--md { padding: calc(12px - var(--kv-btn-stroke-md)) calc(20px - var(--kv-btn-stroke-md)); }
.kv-btn--secondary.kv-btn--sm { padding: calc(12px - var(--kv-btn-stroke-sm)) calc(16px - var(--kv-btn-stroke-sm)); }
.kv-btn--secondary { min-height: calc(32px + var(--kv-lh-sub1)); }
.kv-btn--secondary.kv-btn--md { min-height: calc(24px + var(--kv-lh-sub2)); }
.kv-btn--secondary.kv-btn--sm { min-height: calc(24px + var(--kv-lh-body2)); }

/* ---------------------------------------------------------------------------
   A deactivated call to action, everywhere

   The style guide draws no disabled state for either button, so this is the
   theme's: fifty per cent, and nothing else moves. One rule for every button
   that asks for something and all three ways one can be marked off, because a
   deactivated button should look the same wherever it is and nobody should
   have to remember to say so again.

   - `[disabled]`, the plain one.
   - `[aria-disabled="true"]`, for a button that has to stay reachable by
     keyboard so the reason it is off can be read. The waiting list uses it.
   - `.disabled`, which is WooCommerce's own: the add to cart button wears it
     until a variation has been chosen.

   `pointer-events: none` does the rest. The lift under the pointer and the
   darker ground when pressed are the button saying it will do something, and
   each of them beats a plain opacity on its own; refusing the pointer settles
   every variant at once rather than unpicking hover and active for each. The
   keyboard is untouched, so a button marked `aria-disabled` still takes focus
   and still shows it.

   Not every button on the site: the carousel arrows and the dots have a
   disabled state of their own from the style guide, node 1:998, which is a
   colour rather than a fade.
   ------------------------------------------------------------------------ */
.kv-btn:is([disabled], [aria-disabled="true"], .disabled),
.kv-signup__button:is([disabled], [aria-disabled="true"], .disabled),
.kv-pdp .kv-pdp__buy button[type="submit"]:is([disabled], [aria-disabled="true"], .disabled) {
	opacity: .5;
	box-shadow: none !important;
}

/* Refusing the pointer is only for the two that are genuinely inert.
   WooCommerce's `.disabled` is not a disabled button: the add to cart button
   wears it before a variation has been chosen, and it still has to take the
   press, because that press is what prints "choose a size". Taking the pointer
   away from it turned a button that explains itself into one that does
   nothing at all. */
.kv-btn:is([disabled], [aria-disabled="true"]),
.kv-signup__button:is([disabled], [aria-disabled="true"]),
.kv-pdp .kv-pdp__buy button[type="submit"]:is([disabled], [aria-disabled="true"]) {
	pointer-events: none;
}

/* So the one that keeps its pointer has to be told not to react to it. */
.kv-btn.kv-btn--primary.disabled:hover,
.kv-btn.kv-btn--primary.disabled:active,
.kv-signup__button.disabled:hover,
.kv-signup__button.disabled:active,
.kv-pdp .kv-pdp__buy button[type="submit"].disabled:hover,
.kv-pdp .kv-pdp__buy button[type="submit"].disabled:active {
	background: var(--kv-primary) !important;
	box-shadow: none !important;
}
.kv-btn.kv-btn--secondary.disabled:hover,
.kv-btn.kv-btn--secondary.disabled:active {
	background: none;
	border-color: var(--kv-text);
	color: var(--kv-text);
	box-shadow: none;
}

/* ---------------------------------------------------------------------------
   The banner

   The band at the top of a page: words on one side, a picture on the other,
   running the full width of the screen the way the blog masthead does. The
   About page uses it, and the post hero, the 404 band and anything built later
   are the same shape.

   The picture fills its half at any width. The words do not: they start where
   the left half of the 1136 content column starts, so they line up with the
   bands below them. The cell is half the screen, so anything beyond 568 of it
   is padding, with the gutter as the floor. That is 152 at 1440, which is what
   the frames draw, and 392 at 1920. The 64 on the right is the frame's own gap
   before the half line and holds the measure at 504.

   The halves stack at 1179, picture first, for the reason the other two column
   layouts do: between the frames a picture beside a column of prose leaves the
   prose too narrow.
   ------------------------------------------------------------------------ */

.kv-banner {
	position: relative; overflow: hidden;
	display: grid; grid-template-columns: 1fr 1fr; align-items: center;
	min-height: var(--kv-banner-h);
}
.kv-banner > * { position: relative; z-index: 1; }

.kv-banner__words {
	display: flex; flex-direction: column; gap: var(--kv-banner-gap, 24px);
	padding: var(--kv-banner-pad-y) 64px var(--kv-banner-pad-y) max(var(--kv-gutter), calc(100% - 568px));
}

/* The post hero stands its words at the top of the band rather than centring
   them, node 2:22739. */
.kv-banner--top { align-items: start; }

.kv-banner__media {
	align-self: stretch;
	min-height: var(--kv-banner-h);
	border-radius: 0;
}

@media (max-width: 1179px) {
	.kv-banner { grid-template-columns: 1fr; min-height: 0; }
	.kv-banner__media { order: -1; min-height: 0; height: var(--kv-banner-h-md); }
	.kv-banner__words { padding: var(--kv-banner-pad-y) var(--kv-gutter); }
}

@media (max-width: 767px) {
	.kv-banner { gap: 48px; padding-bottom: 48px; }
	.kv-banner__media { height: var(--kv-banner-h-sm); }
	.kv-banner__words { padding: 0 var(--kv-gutter); gap: 16px; }
}

/* ---------------------------------------------------------------------------
   hidden means hidden

   `[hidden]` is a UA rule setting `display: none`, so any class that sets
   `display` beats it and the element stays on the page while the markup says
   it is gone. It has now caught the shop drawer, the cart's discount body and
   the gallery's image view, each of which needed a patch of its own. One rule
   instead. `!important` is the idiom here: the attribute is the author saying
   the element is not to be shown, which should not lose to a layout rule.
   ------------------------------------------------------------------------ */

[hidden] { display: none !important; }

/* ---------------------------------------------------------------------------
   figcaption

   Hello Elementor's reset gives every figcaption 16px italic in its own grey,
   which is the parent theme's idea of a caption and no frame's. The gallery
   tile was the first to show it; anything else written as a figure would have
   inherited it too. Reset to the body here rather than per component, so a
   caption is styled by what it belongs to.
   ------------------------------------------------------------------------ */

.kv-site figcaption {
	color: inherit; font-size: inherit; font-style: normal;
	font-weight: inherit; line-height: inherit;
}

/* ---------------------------------------------------------------------------
   The caret

   Every disclosure on the site uses the same Phosphor mark, `caret-down`: the
   language switcher, the footer columns, the shop filters, the accordions on a
   term and on a product, the questions, the contents dropdown, the panel and
   the discount row. Each one used to say for itself that it turns over when it
   opens, eleven times in all.

   One rule instead, written against the icon rather than against each
   component, so anything built later gets it by using the mark. A component
   still sets its own size, because the frames draw it at 20, 24, 32 and 40.
   The two that do not open a `<details>` keep their own trigger below: the
   main menu turns on hover, and the cart's discount row on a class.
   ------------------------------------------------------------------------ */

.karivarah-icon--caret-down { transition: transform .2s; }

[open] > summary .karivarah-icon--caret-down,
[aria-expanded="true"] .karivarah-icon--caret-down { transform: rotate(180deg); }

/* ---------------------------------------------------------------------------
   The soft grey lines

   One drawing, `assets/brand/veins.svg`, laid over a tinted band. It was
   written out six times. Two things vary and are the two modifiers below:
   whether it sits under the band's tint or over it, and whether it is anchored
   centre or left, which is what the split banners draw.
   ------------------------------------------------------------------------ */

.kv-veins,
.kv-tcard::before,
.kv-review::before,
.kv-trust::before,
.kv-sitemap::before,
.kv-band--tinted::before,
.kv-prow--veins::before,
.kv-faq__card::before,
.kv-phero::before,
.kv-404__band::before {
	content: ""; position: absolute; inset: 0; pointer-events: none;
	background: url("assets/brand/veins.svg") center / cover no-repeat;
}

/* Under the content. This block lost its declarations in an edit, and the
   five selectors fell into the rule below, which painted a second tint over
   the cards' text. Restored 14.10.2026, the same layer the FAQ card uses. */
.kv-tcard::before,
.kv-review::before,
.kv-trust::before,
.kv-sitemap::before,
.kv-band--tinted::before,
.kv-prow--veins::before { z-index: -1; }

/* The product row brings its own tint, behind the drawing */
.kv-prow--veins::before { background-color: var(--kv-primary-4); }

/* Over it, at half strength */
.kv-veins,
.kv-phero::before,
.kv-404__band::before { z-index: 0; opacity: .5; }

/* Anchored left, which is what a split banner draws */
.kv-phero::before,
.kv-404__band::before { background-position: left center; }

/* ---------------------------------------------------------------------------
   The round button, Component 213 in the style guide, node 1:998

   A circle of Grey/300 with a 32px mark in it, darkening to Grey/800 on hover.
   The gallery steps through its pictures with it.
   ------------------------------------------------------------------------ */

.kv-roundbtn {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 8px; border: 0; border-radius: 1000px;
	background: var(--kv-grey-300); color: var(--kv-text);
	cursor: pointer;
	transition: background-color .15s, color .15s;
}
.kv-roundbtn .karivarah-icon { width: 32px; height: 32px; }
.kv-roundbtn:hover:not([disabled]),
.kv-roundbtn:focus-visible:not([disabled]) { background: var(--kv-grey-800); color: var(--kv-text); }
.kv-roundbtn[disabled] { color: var(--kv-text-disabled); cursor: default; }

/* ---------------------------------------------------------------------------
   The lightbox

   The shell a picture is opened over: the product page's magnifier and the
   gallery's image view are both this. One `<dialog>` the size of the screen,
   the overlay behind it, a panel in the middle, the close in the corner and a
   round button either side.

   Only the panel differs between the two, so only the panel is written twice.
   The overlay is a token because the two frames do not agree: the magnifier is
   drawn over the near black and the gallery over black at 40%.
   ------------------------------------------------------------------------ */

dialog.kv-lightbox {
	width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
	margin: 0; padding: 0; border: 0; background: none;
	--kv-lightbox-backdrop: rgba(0, 0, 0, .4);
}
dialog.kv-lightbox[open] { display: grid; place-items: center; overflow: hidden; }
dialog.kv-lightbox::backdrop { background: var(--kv-lightbox-backdrop); }

.kv-lightbox__panel { position: relative; }

.kv-lightbox .kv-lightbox__close,
.kv-lightbox .kv-lightbox__close:focus {
	position: absolute; top: 0; left: calc(100% + 112px); z-index: 3;
	width: 40px; height: 40px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 4px !important; border: 0 !important; border-radius: 100px;
	background: none !important; color: var(--kv-paper) !important; cursor: pointer;
}
.kv-lightbox__close .karivarah-icon { width: 32px; height: 32px; }

.kv-lightbox .kv-lightbox__nav {
	position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
}
.kv-lightbox__nav--prev { right: calc(100% + 62px); }
.kv-lightbox__nav--next { left: calc(100% + 62px); }

/* Below the width where a button can sit outside the card, both move inside
   it, which is what the magnifier already does. */
@media (max-width: 1024px) {
	.kv-lightbox .kv-lightbox__close,
	.kv-lightbox .kv-lightbox__close:focus { left: auto; right: 8px; top: 8px; background: var(--kv-paper) !important; color: var(--kv-text) !important; }
	.kv-lightbox__nav--prev { right: auto; left: 8px; }
	.kv-lightbox__nav--next { left: auto; right: 8px; }
}

/* ---------------------------------------------------------------------------
   Icons
   ------------------------------------------------------------------------ */

.karivarah-icon { width: 24px; height: 24px; display: inline-block; vertical-align: middle; flex: 0 0 auto; }

/* A floor for the commissioned set.
 *
 * Those marks carry far more detail than a generic one, so they stop reading
 * before a Phosphor arrow does: at 20 and 24 the header, the accordion rows
 * and the notices were showing mush. `min-width` raises the used size wherever
 * a component asks for less, without touching any of the sizes already above
 * it, so the rule is one line rather than forty edits. Phosphor is untouched:
 * an arrow, a caret or a cross reads fine small, which is what they are for.
 *
 * The room comes out of the touch targets, which were larger than their icons
 * anyway. Where a target was exactly the icon's size it grows with it. */
:root { --kv-icon-min: 32px; }
.karivarah-icon--brand { min-width: var(--kv-icon-min); min-height: var(--kv-icon-min); }

/* Two exceptions. The star is a plain shape that reads at any size and sets
   the height of the review rows, and the wave is set in a line of text. */
.karivarah-icon--star,
.kv-acct__wave .karivarah-icon { min-width: 0; min-height: 0; }
.kv-ico-16 { width: 16px; height: 16px; }
.kv-ico-20 { width: 20px; height: 20px; }
.kv-ico-primary { color: var(--kv-primary); }

/* ---------------------------------------------------------------------------
   Header
   ------------------------------------------------------------------------ */

.kv-header { box-shadow: var(--kv-elevation-3); position: relative; z-index: 100; }

.kv-announce { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-announce p { margin: 0; display: flex; align-items: center; gap: 4px; }

@media (max-width: 767px) { .kv-announce { height: 36px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); } }
@media (prefers-reduced-motion: reduce) {
	.kv-announce > .e-con-inner, .kv-announce > .elementor-widget-wrap { animation: none; }
}

/* Search */
.kv-search__label {
	display: flex; align-items: center; gap: 4px;
	border: 1px solid var(--kv-grey-900); border-radius: var(--kv-radius);
	/* The stroke comes out of the padding, the way the secondary button's
	   does: the frame draws a 48 tall field on a 24 icon and 12 of padding,
	   node 1:1223, and a border added on top of that made it 50. */
	padding: 11px; background: var(--kv-paper);
}
.kv-search__icon { color: var(--kv-text-2); }
.kv-search__input {
	border: 0; padding: 0; background: none; width: 100%;
	font: inherit; color: var(--kv-text); line-height: 24px;
}
.kv-search__input::placeholder { color: var(--kv-text-2); opacity: 1; }
.kv-search__input:focus { outline: none; }
/* Primary at half strength while it has focus, node 1:1175. */
.kv-search__label:focus-within { border-color: var(--kv-primary-50); }

/* The cross, which is only there once there is something to clear. */
.kv-search__clear {
	display: inline-flex; align-items: center; justify-content: center;
	width: 16px; height: 16px; padding: 0; border: 0; background: none;
	color: var(--kv-text); cursor: pointer; flex: 0 0 16px;
}
.kv-search__clear .karivarah-icon { width: 16px; height: 16px; }
/* The cross is drawn at the size the frame draws it, and the thumb is given
   room around it instead: a box on the pseudo-element shifts nothing. */
.kv-search__clear { position: relative; }
.kv-search__clear::after { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 32px; height: 32px; }
.kv-search__clear:focus-visible { outline: 2px solid var(--kv-primary); outline-offset: 2px; border-radius: 4px; }

/* The list, node 1:1216. It hangs off the field, which is why the form is the
   positioned element: the field itself is a label and the list has to clear
   its border rather than sit inside it. */
.kv-search { position: relative; }
.kv-search__results {
	position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40;
	display: flex; flex-direction: column;
	border-radius: 16px; overflow: hidden;
	background: var(--kv-paper); box-shadow: var(--kv-elevation-4);
}
/* One line a row, as the frame draws it: a product name can run to sixty
   characters and three wrapped rows would push the way out of the list off
   the bottom of the screen. The whole name is on the page it opens. */
.kv-search__row {
	display: flex; align-items: center; gap: 8px;
	padding: 8px 16px; background: var(--kv-paper);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text) !important; text-decoration: none;
	white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* The name is a flex item, so it is the item that truncates: ellipsis does
   nothing to the anonymous text of a flex container. */
.kv-search__row > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.kv-search__row:hover,
.kv-search__row.is-on { background: var(--kv-grey-200); }
/* The way through to everything is the same link the Butikk dropdown uses for
   "Se alle produkter", node I2:131358: the words, then the arrow beside them
   at 20, and both turning Primary together on hover. */
.kv-search__all { gap: 8px; }
.kv-search__all > span { flex: 0 1 auto; }
.kv-search__all .karivarah-icon { color: inherit; }
.kv-search__all:hover,
.kv-search__all.is-on { color: var(--kv-primary) !important; }
.kv-search__none {
	margin: 0; padding: 8px 16px; background: var(--kv-paper);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2);
}
.kv-header__wide .kv-search { width: 264px; }
.kv-header__search .kv-search { width: 100%; }
/* Phone: the field is 40px tall on a 20px icon, node 2:23344. */
@media (max-width: 767px) {
	.kv-search__label { height: 40px; padding: 0 12px; }
	.kv-search__label .kv-search__icon { width: 20px; height: 20px; }
	.kv-search__input { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	/* The small field's cross and rows, node 1:1228. */
	.kv-search__clear,
	.kv-search__clear .karivarah-icon { width: 12px; height: 12px; flex-basis: 12px; }
	.kv-search__row,
	.kv-search__none { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
}

/* Icon links, each with a 48px tap target */
/* `flex`, not `inline-flex`: inline level put a text baseline under each mark
   and the row stood 50 where the frame draws 48, node 1:1379. */
.kv-iconlink {
	position: relative; display: flex; align-items: center; justify-content: center;
	width: 48px; height: 48px; color: var(--kv-text); text-decoration: none;
}
.kv-cart-wrap { display: block; }
.kv-iconlink:hover { color: var(--kv-primary); }
.kv-badge {
	position: absolute; top: 3px; left: 26px;
	min-width: 19px; height: 19px; padding: 0 5px;
	border-radius: 100px; background: var(--kv-text); color: var(--kv-white);
	font-size: 12px; line-height: 19px; text-align: center;
}

/* Language switcher: the current language, the rest behind a caret */
.kv-lang { position: relative; }
.kv-lang__current {
	display: inline-flex; align-items: center; gap: 6px;
	list-style: none; cursor: pointer; padding: 6px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
/* In the header the frame gives the switcher no padding of its own and two
   pixels before the caret, node 1:1657, which is 72 wide against the 88 a
   six-pixel pad and a six-pixel gap made. The thumb keeps its room through a
   box on the pseudo-element, so nothing on screen moves. */
/* The switcher sits on a text line otherwise, and the eight pixels under it
   pushed the open list to 16 below the trigger where the frame puts 8. */
.kv-header .kv-lang { display: inline-flex; }
.kv-header .kv-lang__current { padding: 0; gap: 0; position: relative; }
.kv-header .kv-lang__code { margin: 0 2px 0 6px; }
.kv-header .kv-lang__current::after { content: ""; position: absolute; inset: -8px -6px; }
/* And the row of marks sits against the switcher. The frame puts 24 between
   the search field and that row and nothing between the switcher and the
   account mark, node 1:1379, where the Elementor container spaces all three
   of its children alike. So the container's gap goes and the gap is carried
   by the search field instead. */
.kv-header__wide .e-con-inner:has(> * > .elementor-shortcode > .kv-search) { gap: 0; }
.kv-header__wide .e-con-inner > *:has(> .elementor-shortcode > .kv-search) { margin-right: 24px; }
.kv-lang__current::-webkit-details-marker { display: none; }
.kv-lang__flag { width: 20px; height: 20px; border-radius: 100px; object-fit: cover; display: block; }
.kv-lang__caret { width: 20px; height: 20px; transition: transform .15s; }
/* The open list, node 1:1699: Grey/100 on a Grey/300 stroke, an 8 radius,
   Elevation 3 under it, and centred on the trigger rather than hung from its
   left edge. The rows carry their own 12 and 6, so the box has no padding. */
.kv-lang__list {
	position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%); z-index: 20;
	list-style: none; margin: 0; padding: 0; overflow: hidden;
	background: var(--kv-grey-100); border: 1px solid var(--kv-grey-300);
	border-radius: 8px; box-shadow: var(--kv-elevation-3);
}
.kv-lang__list a {
	display: flex; align-items: center; gap: 6px;
	padding: 6px 12px; color: var(--kv-text); text-decoration: none; white-space: nowrap;
}
/* The language being read keeps its place in the list with a mark against
   it, which is the green the frames use for a chosen thing. */
.kv-lang__tick { width: 20px; height: 20px; margin-left: 2px; color: var(--kv-success); }
.kv-lang__opt.is-here { cursor: default; }
.kv-footer .kv-lang__list { background: var(--kv-text); }
.kv-footer .kv-lang__list a { color: var(--kv-page); }

/* Menu trigger */
.kv-menu-toggle {
	display: inline-flex; align-items: center; justify-content: center;
	width: 48px; height: 48px; padding: 0; border: 0; background: none;
	color: var(--kv-text); cursor: pointer;
}

/* Newsletter strip */
.kv-newsletter { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-newsletter p { margin: 0; }
.kv-newsletter a { color: var(--kv-text); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.kv-newsletter strong { font-weight: var(--kv-weight-semibold); }
@media (max-width: 767px) { .kv-newsletter { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); } }


/* Logo */
/* Block level, not inline: an inline-flex anchor sits on a text baseline and
   the line box under it put ten pixels into the header row, which stood 106
   against the frame's 96, node 1:1357. */
.kv-logo-link { display: flex; }
/* The frame's slot is 104 by 56, node 1:1359, and the artwork's own ratio
   makes it 56.46 at that width, which left the row half a pixel tall. The
   slot takes the frame's height and the drawing keeps its proportions
   inside it. */
.kv-header .kv-logo { height: 56px; }
/* The phone draws the same mark in an 89 by 48 slot, node 1:1429. */
@media (max-width: 767px) { .kv-header .kv-logo { height: 48px; } }
.kv-logo { width: 104px; height: auto; display: block; }
@media (max-width: 1024px) { .kv-logo { width: 104px; } }
@media (max-width: 767px)  { .kv-logo { width: 89px; } }

/* Header groups: shrink to their contents so space-between works */
.kv-hgroup { width: auto !important; flex: 0 0 auto !important; }
.kv-header__wide > .e-con-inner > .kv-hgroup,
.kv-header__wide > .kv-hgroup { width: auto !important; }
@media (max-width: 767px) { .kv-hide-mobile { display: none !important; } }

/* ---------------------------------------------------------------------------
   Main navigation. Written against Elementor's own classes so the widget's
   defaults do not have to be fought in the builder.
   ------------------------------------------------------------------------ */

.kv-nav .elementor-nav-menu { gap: 24px; }
.kv-nav .elementor-nav-menu--main .elementor-item {
	font-size: var(--kv-fs-body1);
	line-height: var(--kv-lh-body1);
	font-weight: var(--kv-weight);
	color: var(--kv-text-2);
	padding: 0;
	fill: currentColor;
}
.kv-nav .elementor-nav-menu--main .elementor-item:hover,
.kv-nav .elementor-nav-menu--main .elementor-item.elementor-item-active,
.kv-nav .elementor-nav-menu--main .current-menu-item > .elementor-item { color: var(--kv-primary); }
.kv-nav .elementor-nav-menu--main .elementor-item.elementor-item-active:after,
.kv-nav .elementor-nav-menu--main .elementor-item:after { display: none; }

/* Submenu: the Shop dropdown */
.kv-nav .elementor-nav-menu--dropdown { background: var(--kv-paper); box-shadow: var(--kv-elevation-3); border-radius: var(--kv-radius); padding: 8px 0; }
.kv-nav .elementor-nav-menu--dropdown a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); padding: 8px 20px; }
.kv-nav .elementor-nav-menu--dropdown a:hover { color: var(--kv-primary); background: var(--kv-grey-300); }

/* Compact search spans the row */
.kv-header__search > .e-con-inner { width: 100%; }
.kv-header__search .elementor-widget-shortcode,
.kv-header__search .elementor-shortcode { width: 100%; }

/* ---------------------------------------------------------------------------
   Search, written to beat Hello and WooCommerce's own input styling rather
   than rely on source order.
   ------------------------------------------------------------------------ */

.kv-search { width: 100%; }
.kv-search .kv-search__label { margin: 0; }
.kv-search input[type="search"].kv-search__input {
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	background: transparent !important;
	padding: 0 !important;
	margin: 0 !important;
	height: auto !important;
	min-height: 0 !important;
	width: 100% !important;
	font-size: var(--kv-fs-body1);
	line-height: var(--kv-lh-body1);
	-webkit-appearance: none;
	appearance: none;
}
.kv-search input[type="search"].kv-search__input:focus { outline: 0 !important; box-shadow: none !important; }
.kv-search input[type="search"]::-webkit-search-cancel-button { display: none; }

.kv-header__wide .kv-search { width: 264px; flex: 0 0 264px; }
.kv-header__search .kv-search { width: 100%; }
@media (max-width: 767px) { .kv-search input[type="search"].kv-search__input { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); } }

/* The compact header's groups should not stretch */
.kv-header__compact > .e-con-inner { width: 100%; }

/* The logo is an inline-flex link inside a block, so the line box was adding
   descender space under it and making the row 10px taller than the frame's 76. */
.kv-header__compact .elementor-shortcode { display: flex; }

/* ---------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------ */

.kv-footer { color: var(--kv-page); }
.kv-footer p { margin: 0; }
.kv-footer a { color: var(--kv-page); text-decoration: none; }

.kv-foot__h.elementor-widget-heading .elementor-heading-title {
	font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); font-weight: var(--kv-weight-semibold); color: var(--kv-white);
}
.kv-foot__coltitle.elementor-widget-heading .elementor-heading-title {
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); font-weight: var(--kv-weight-semibold); color: var(--kv-white);
}
.kv-foot__signup-copy { max-width: 485px; }
/* The frame groups the heading with the sentence under it at 16 and spaces
   the rest of the block at 20, node 1:1832. Elementor gives the container
   one gap, so the heading gives four back. */
.kv-footer .kv-foot__h { margin-bottom: -4px; }
.kv-foot__consent { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
.kv-foot__consent a { text-decoration: underline; }

/* Signup form */
.kv-signup { display: flex; gap: 12px; width: 100%; }
.kv-signup__button {
	flex: 0 0 auto; border: 0; cursor: pointer;
	background: var(--kv-primary); color: var(--kv-white);
	border-radius: 16px; padding: 16px 24px;
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
}
.kv-signup__button:focus-visible { background: var(--kv-primary); box-shadow: var(--kv-elevation-primary); }
@media (hover: hover) {
	.kv-signup__button:hover { background: var(--kv-primary); box-shadow: var(--kv-elevation-primary); }
}
.kv-signup__button:active { background: var(--kv-primary-dark); box-shadow: var(--kv-elevation-primary); }
/* The field and its button stay on one row at every width, nodes 1:1987 and
   1:2140. The phone draws them side by side too, both at the small size. */
@media (max-width: 767px) {
	.kv-signup { flex-direction: row; }
	.kv-signup__button { width: auto; }
	.kv-footer .kv-signup__button {
		padding: 12px 16px; border-radius: var(--kv-btn-radius-sm);
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-field .kv-field__input {
		padding: 11px 15px; border-radius: var(--kv-btn-radius-sm);
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-field__label {
		left: 16px; top: 12px;
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-field__input:focus + .kv-field__label,
	.kv-footer .kv-field__input:not(:placeholder-shown) + .kv-field__label { transform: translateY(-9px); }
	.kv-footer .kv-field .kv-field__input:focus,
	.kv-footer .kv-field .kv-field__input:not(:placeholder-shown) { padding-top: 17px; padding-bottom: 5px; }
	/* The heading is H6 and the words under it Body 2, node 1:2138, and the
	   block closes to 16 with 12 between the heading and the sentence. */
	.kv-footer .kv-foot__h.elementor-widget-heading .elementor-heading-title {
		font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6);
	}
	.kv-footer .kv-foot__signup-copy .elementor-widget-text-editor p,
	.kv-footer .kv-foot__brand .elementor-widget-text-editor p {
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-foot__signup-copy > .e-con-inner { gap: 16px; }
	.kv-footer .kv-foot__h { margin-bottom: -4px; }
}

/* Columns */
.kv-foot__brand { width: 380px; max-width: 100%; }
.kv-foot__links { flex: 1 1 auto; }
.kv-foot__logo .kv-logo { width: 147px; }
.kv-foot__logo .kv-logo path[fill="#231f20"] { fill: var(--kv-page); }
.kv-foot__menu .elementor-nav-menu { gap: 8px; }
.kv-foot__menu .elementor-nav-menu--main .elementor-item {
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); font-weight: var(--kv-weight);
	color: var(--kv-page); padding: 0;
}
.kv-foot__menu .elementor-nav-menu--main .elementor-item:hover,
.kv-foot__menu .current-menu-item > .elementor-item { color: var(--kv-primary-light); }

/* The footer lists are plain menu markup rather than Elementor's own links,
   so the rule above never reached them: the page a reader is on was printing
   like every other line. */
.kv-foot__links .current-menu-item > a,
.kv-foot__links .current_page_item > a,
.kv-foot__links a[aria-current="page"] { color: var(--kv-primary-light); }

/* On the dark footer the brand orange is 3.9:1 and the field's grey label
   3.0:1, both under the 4.5 text needs, so the footer takes the light orange
   and black/200. Field errors take the light red for the same reason: the
   dark red that passes on white is 3.1:1 here. */
.kv-footer .kv-field__label { color: var(--kv-black-200); }
.kv-footer .kv-field__error,
.kv-footer .kv-field.is-wrong .kv-field__label { color: var(--kv-error-light); }

/* Social */
.kv-social { display: flex; gap: 8px; list-style: none; margin: 0; padding: 0; }
.kv-social a { display: inline-flex; padding: 8px; border-radius: 100px; background: rgba(255,255,255,0.05); }
.kv-social__icon { width: 20px; height: 20px; display: block; }

/* Contact block */
.kv-contact { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-contact__label { display: inline-flex; align-items: center; gap: 4px; }
.kv-contact__value { display: block; }
/* The one row with a label as well as a value reads as one line: the number is
   the label's second half, not a line of its own. `kv-contact__value` is block
   because every other row is a value on its own. */
.kv-contact__org .kv-contact__value { display: inline; }
.kv-contact__org { white-space: nowrap; }

/* Payment and shipping marks */
.kv-marks { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; flex-wrap: wrap; }
.kv-marks--pay { gap: 12px; }
.kv-marks--ship { gap: 16px; }
.kv-marks svg { display: block; height: 24px; width: auto; }
.kv-marks--ship svg { height: 20px; }

/* Carrier marks are balanced by eye, not by box height, because the three
   lockups are built differently. Measured at a common height, the share of the
   box each wordmark fills is Posten 0.54, PostNord 1.00, Helthjem 0.72:
   PostNord is wordmark and nothing else, so at a shared height it reads far
   larger than the two that spend part of their box on a symbol. These heights
   bring the three wordmarks to the same size, which is what the eye compares.
   They stay centred on one line, and the spread is 2px rather than the 8px that
   made Posten look out of line. */
/* Centring the boxes does not centre the lettering, because each wordmark sits
   at a different depth in its box: the baseline falls at 0.865 of the box in
   Posten and 0.82 in the other two, and the boxes are different heights. Left
   centred, PostNord's baseline sat 1.6px above Helthjem's and Posten's 1.6px
   below. These shifts put all three on Helthjem's baseline. */
.kv-marks--ship .kv-mark--posten svg { height: 22px; transform: translateY(-1.6px); }
.kv-marks--ship .kv-mark--postnord svg { height: 15px; transform: translateY(1.6px); }
.kv-marks--ship .kv-mark--helthjem svg { height: 20px; }

/* Legal line */
.kv-foot__legal { width: 100%; border-top: 1px solid var(--kv-text-2); padding-top: 24px !important; }
.kv-foot__copy { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-disabled); text-align: center; }

.kv-footer .e-con-inner { max-width: 1136px; }

/* Text inside the footer inherits the page's dark body colour otherwise */
.kv-footer .elementor-widget-text-editor,
.kv-footer .elementor-widget-text-editor p,
.kv-footer .elementor-widget-shortcode,
.kv-footer .kv-contact { color: var(--kv-page); }
.kv-footer .elementor-widget-text-editor p { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-footer .kv-foot__consent, .kv-footer .kv-foot__consent p { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
.kv-footer .kv-foot__copy { color: var(--kv-text-disabled); }

/* The wordmark is near-black in the brand file; invert it on the dark ground */
.kv-foot__logo .kv-logo path { fill: var(--kv-page); }
.kv-foot__logo .kv-logo path[fill="#cb5827" i] { fill: var(--kv-primary); }

/* No underline pointer on menus */
.kv-nav .elementor-nav-menu--main .elementor-item:before,
.kv-nav .elementor-nav-menu--main .elementor-item:after,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:before,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:after { display: none !important; }

/* Theme images */
.kv-picture, .kv-picture img { display: block; max-width: 100%; height: auto; }

/* When the signup block stacks, the illustration leads. Elementor writes its own
   flex-direction for the tablet breakpoint, so this has to win on specificity. */
/* The signup block is a row down to the tablet layout; only the phone stacks it,
   and there the illustration leads. */
@media (max-width: 767px) {
	.kv-footer .kv-foot__signup,
	.kv-footer .kv-foot__signup > .e-con-inner { flex-direction: column-reverse !important; }
	.kv-foot__signup-copy { max-width: none; }
}
@media (min-width: 768px) and (max-width: 1024px) {
	.kv-footer .kv-foot__signup { flex-direction: row !important; align-items: center !important; }
	.kv-foot__signup-copy { max-width: 50%; }
}

/* Stacked signup: the copy column must fill the row rather than shrink-wrap to
   its longest line, which is what pushed the heading off a 375 screen. */
@media (max-width: 767px) {
	.kv-footer .kv-foot__signup > * { width: 100% !important; min-width: 0 !important; flex: 0 0 auto !important; }
	.kv-foot__signup-copy { max-width: 100%; }
}
@media (max-width: 767px) {
	.kv-footer .elementor-widget-text-editor p { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
}

/* The three link columns sat in a fixed row, which held the whole footer wider
   than a phone screen and pushed every other block off the right edge. */
.kv-footer .e-con, .kv-footer .e-con-inner { max-width: 100%; }

/* ---------------------------------------------------------------------------
   Nothing in the header or footer may be wider than the screen. One element
   that overflows gives the whole document a horizontal scroll, and then every
   other section looks cut off even though it is not.
   ------------------------------------------------------------------------ */

.kv-header .e-con, .kv-header .e-con-inner,
.kv-footer .e-con, .kv-footer .e-con-inner { max-width: 100%; }

.kv-newsletter .elementor-widget-text-editor { max-width: 100%; }
.kv-newsletter p { text-align: center; }
.kv-newsletter a { display: inline; }
.kv-newsletter a .karivarah-icon { vertical-align: -5px; }

/* ---------------------------------------------------------------------------
   Menu hover must change colour and nothing else.
   Elementor ships `.elementor-nav-menu a:hover { padding:10px 20px; line-height:20px }`,
   and because a pseudo-class counts toward specificity that rule outranks a
   plain `.elementor-item` rule. So the hover and focus states are spelled out.
   ------------------------------------------------------------------------ */

.kv-nav .elementor-nav-menu--main .elementor-item,
.kv-nav .elementor-nav-menu--main .elementor-item:hover,
.kv-nav .elementor-nav-menu--main .elementor-item:focus,
.kv-nav .elementor-nav-menu--main .elementor-item:active,
.kv-foot__menu .elementor-nav-menu--main .elementor-item,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:hover,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:focus,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:active {
	padding: 0;
	line-height: 24px;
	border: 0;
	transform: none;
	text-decoration: none;
}

.kv-nav .elementor-nav-menu--main .elementor-item:hover,
.kv-foot__menu .elementor-nav-menu--main .elementor-item:hover { color: var(--kv-primary-light); }

/* ---------------------------------------------------------------------------
   Submenu arrow: Elementor's own indicator is off in the header template and
   the caret is printed into the link by inc/shop-menu.php, so it is the same
   Phosphor icon the rest of the site uses and takes the link's colour.
   ------------------------------------------------------------------------ */

.kv-nav .elementor-item .kv-nav__caret {
	width: 24px; height: 24px; margin-inline-start: 4px;
	vertical-align: middle; transition: transform .15s;
}
.kv-nav .elementor-nav-menu--main li:hover > a .kv-nav__caret { transform: rotate(180deg); }

/* The kit styles every link at `.elementor-kit-N a`, which outranks a single
   class. These need the extra specificity to keep the design's colours. */
.kv-header .kv-iconlink,
.kv-header .kv-iconlink:link,
.kv-header .kv-iconlink:visited { color: var(--kv-text); }
.kv-header .kv-iconlink:hover { color: var(--kv-primary); }
.kv-header .kv-lang__current,
.kv-header .kv-lang__list a { color: var(--kv-text); }
.kv-header .kv-newsletter p a, .kv-newsletter p a:link { color: var(--kv-text); }

/* Hello sets `img { height: auto }`, which stops the flag being cropped square,
   so it has to be pinned here to come out round as the frame draws it. */
.kv-lang .kv-lang__flag {
	width: 20px !important;
	height: 20px !important;
	border-radius: 100px;
	object-fit: cover;
	background: var(--kv-grey-600);
	flex: 0 0 auto;
}
.kv-icons { gap: 0 !important; }
.kv-icons .elementor-widget-shortcode { margin: 0; }

/* ---------------------------------------------------------------------------
   Announcement strip, below the desktop breakpoint.

   One sentence at a time, centred. Each one rises out of the top while the
   next rises into its place from below, so the motion is always upward. Each
   item runs the same animation, offset by half the cycle, which avoids
   duplicating the copy to fake a loop: the only jump is from above the strip
   back to below it, and that happens while the item is out of sight.

   A third sentence needs a third delay below and the cycle split in three.
   ------------------------------------------------------------------------ */

@media (max-width: 1024px) {
	.kv-header .kv-announce,
	.kv-header .kv-announce > .e-con-inner {
		position: relative;
		height: 40px;
		overflow: hidden;
		padding: 0 16px !important;
		display: block !important;
	}
	.kv-header .kv-announce .elementor-widget-text-editor {
		position: absolute;
		inset: 0;
		display: flex;
		align-items: center;
		justify-content: center;
		width: auto;
		animation: kv-ticker 12s infinite;
	}
	.kv-header .kv-announce .elementor-widget-text-editor:nth-of-type(2) { animation-delay: -6s; }
	.kv-header .kv-announce p { justify-content: center; margin: 0; }

	/* Hold, then rise out of the top. The waiting sentence sits below and rises
	   into place over the same 0.48s, so the two always move together and the
	   strip is never empty. The jump from above to below happens out of sight. */
	@keyframes kv-ticker {
		0%, 46%  { transform: translateY(0); }
		50%      { transform: translateY(-100%); }
		50.01%   { transform: translateY(100%); }
		96%      { transform: translateY(100%); }
		100%     { transform: translateY(0); }
	}
}

@media (max-width: 767px) {
	.kv-header .kv-announce,
	.kv-header .kv-announce > .e-con-inner { height: 36px; }
	.kv-header .kv-announce .elementor-widget-text-editor { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
}

/* Someone who has asked for less motion sees the first sentence, held still. */
@media (prefers-reduced-motion: reduce) {
	.kv-header .kv-announce .elementor-widget-text-editor { animation: none; transform: translateY(0); }
	.kv-header .kv-announce .elementor-widget-text-editor:nth-of-type(2) { display: none; }
}

/* ---------------------------------------------------------------------------
   Footer columns: open on desktop, collapsed behind their heading below that.
   ------------------------------------------------------------------------ */

.kv-foot__col { width: 100%; }
.kv-foot__coltitle {
	display: flex; align-items: center; justify-content: space-between; gap: 8px;
	list-style: none; cursor: default;
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); font-weight: var(--kv-weight-semibold); color: var(--kv-white);
}
.kv-foot__coltitle::-webkit-details-marker { display: none; }
/* The columns carry no `open` attribute, so that the phone opens with the
   headings alone. Above the phone there is no toggle to speak of, so the body
   shows whether the element is open or not. */
@media (min-width: 768px) {
	.kv-foot__col:not([open]) > .kv-foot__colbody { display: block; }
}
.kv-foot__caret { width: 24px; height: 24px; display: none; transition: transform .15s; }
.kv-foot__colbody { padding-top: 24px; }

.kv-menu { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.kv-menu a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-page); text-decoration: none; }
.kv-menu .current-menu-item > a { color: var(--kv-primary-light); }
.kv-foot__colbody .kv-contact { margin-top: 8px; }

/* ---------------------------------------------------------------------------
   Compact header: the logo is centred on the screen, not between its
   neighbours, so the unequal widths either side do not pull it off centre.
   ------------------------------------------------------------------------ */

@media (max-width: 1024px) {
	.kv-header .kv-header__compact {
		display: grid !important;
		grid-template-columns: 1fr auto 1fr;
		align-items: center;
	}
	.kv-header .kv-header__compact > :first-child { justify-self: start; }
	.kv-header .kv-header__compact > :last-child { justify-self: end; }
}

/* ---------------------------------------------------------------------------
   Footer columns by width, following the three frames.

   1440: brand beside three open columns.
    834: two columns, open, brand and Quick links on the left, Need help and
         Customer service on the right.
    375: everything stacked, each column collapsed behind its heading.
   ------------------------------------------------------------------------ */

@media (min-width: 768px) and (max-width: 1024px) {
	.kv-footer .kv-foot__cols {
		display: grid !important;
		grid-template-columns: 1fr 1fr;
		/* The frame stacks each column's two blocks 48 apart, node 1:1993. */
		gap: 48px;
	}
	/* The tablet footer is its own size, node 1:1980: 36 between the bands,
	   24 across the sign-up row, the heading at H6, the words at Body 2 and
	   the field and its button at the small size. */
	.kv-footer { gap: 36px !important; }
	.kv-footer .kv-foot__signup { gap: 24px !important; }
	.kv-footer .kv-foot__signup > .kv-foot__signup-copy { width: 344px !important; flex: 0 0 344px !important; max-width: 344px; }
	.kv-footer .kv-foot__signup > .kv-foot__illustration { flex: 1 1 auto !important; min-width: 0; }
	.kv-foot__h.elementor-widget-heading .elementor-heading-title {
		font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6);
	}
	.kv-footer .kv-foot__signup-copy .elementor-widget-text-editor p,
	.kv-footer .kv-foot__brand .elementor-widget-text-editor p {
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-signup__button {
		padding: 12px 16px; border-radius: var(--kv-btn-radius-sm);
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-foot__links { display: contents !important; }
	.kv-footer .kv-foot__brand { grid-column: 1; grid-row: 1; width: 100% !important; }
	.kv-footer .kv-foot__links > :nth-child(1) { grid-column: 1; grid-row: 2; }
	.kv-footer .kv-foot__links > :nth-child(2) { grid-column: 2; grid-row: 1; }
	.kv-footer .kv-foot__links > :nth-child(3) { grid-column: 2; grid-row: 2; }
}

/* The payment and shipping row, nodes I2:27777;18482:88667 at 1440 and
   I2:27846;18482:88478 at 834. Elementor gives both columns half the row, so
   the shipping marks sat stranded in the middle of their half with 300px of
   empty space between them and the margin. The design sizes each column to its
   content instead, and then places them differently at each width: at 1440 they
   sit apart with the shipping block's right edge on the margin at 1136, at 834
   they sit together with a 48px gap and the right margin left clear, and on the
   phone they stack at the gutter. Only the width is taken off Elementor here;
   its own space-between does the rest at desktop. */
@media (min-width: 768px) {
	.kv-footer .kv-foot__marks > .e-con.e-con { --width: auto; }
}
@media (min-width: 768px) and (max-width: 1179px) {
	.kv-footer .kv-foot__marks { justify-content: flex-start; gap: 48px; }
}

@media (max-width: 767px) {
	.kv-footer .kv-foot__cols { flex-direction: column !important; gap: 32px !important; }
	.kv-footer .kv-foot__links { flex-direction: column !important; gap: 24px !important; width: 100% !important; }
	.kv-footer .kv-foot__links > * { flex: 0 0 auto !important; width: 100% !important; }
	.kv-footer .kv-foot__brand { width: 100% !important; }
	.kv-footer .kv-foot__marks { gap: 32px !important; }

	/* Only the phone collapses the columns. */
	.kv-foot__coltitle { cursor: pointer; }
	.kv-foot__caret { display: block; }
	.kv-foot__colbody { padding-top: 16px; }
	.kv-foot__col { padding-bottom: 8px; }
}

/* ---------------------------------------------------------------------------
   Between the tablet breakpoint and 1440 there is no frame to follow, and the
   1440 layout does not fit: 152px gutters plus the logo, menu, 264px search and
   three icons overflow a 1180px iPad by 24px. So the gutter scales with the
   viewport up to the drawn 152px, and the search box is allowed to give way
   before anything else does.
   ------------------------------------------------------------------------ */

@media (min-width: 1025px) and (max-width: 1439px) {
	.kv-header .kv-header__wide {
		padding-left: clamp(24px, 10.5vw, 152px) !important;
		padding-right: clamp(24px, 10.5vw, 152px) !important;
	}
	.kv-footer {
		padding-left: clamp(24px, 10.5vw, 152px) !important;
		padding-right: clamp(24px, 10.5vw, 152px) !important;
	}
	.kv-header .kv-header__wide .kv-hgroup { min-width: 0 !important; }
	.kv-header .kv-header__wide .kv-search { flex: 0 1 264px !important; min-width: 150px; }
	.kv-nav .elementor-nav-menu { gap: 20px; }
}

/* ---------------------------------------------------------------------------
   Footer link columns: equal widths, and long names wrap rather than setting
   the column width. "Personvernerklæring" and "Return and Refund Policy" are
   the ones that decide this.
   ------------------------------------------------------------------------ */

.kv-foot__links > * { flex: 1 1 0 !important; min-width: 0 !important; }
.kv-menu a { white-space: normal; overflow-wrap: break-word; hyphens: auto; }
.kv-foot__coltitle { overflow-wrap: break-word; }

/* ---------------------------------------------------------------------------
   The footer against its frame, node 1:1828, measured 12.10.2026

   Elementor sizes the containers by percentage and the frame sizes them by
   content, so each band was a different shape: the sign-up words took 709
   where the frame gives them 485, the illustration 322 against 516, and the
   brand column 265 against 380. The gaps were short too, 48 between the bands
   where the frame has 64.
   ------------------------------------------------------------------------ */
@media (min-width: 1025px) {
	.kv-footer { gap: 64px !important; }
	/* Exact at 1440 and shrinking below it: between 1025 and 1440 the gutter
	   itself narrows, so fixed widths here pushed the page into a sideways
	   scroll at 1200. */
	.kv-footer .kv-foot__signup > .kv-foot__signup-copy { width: 485px !important; flex: 0 1 485px !important; min-width: 0 !important; }
	.kv-footer .kv-foot__signup > .kv-foot__illustration { width: 516px !important; flex: 0 1 516px !important; min-width: 0 !important; }
	.kv-footer .kv-foot__cols > .kv-foot__brand { width: 380px !important; flex: 0 1 380px !important; min-width: 0 !important; }
	.kv-footer .kv-foot__links { gap: 48px !important; }
	.kv-footer .kv-foot__cols { gap: 120px !important; }
}
/* The frame draws the illustration in a 516 by 280 window with the artwork
   running past it top and bottom, node 1:1839. The export is a tighter crop
   of the same drawing, so the window takes the frame's height and the
   drawing fills it. */
/* The frame draws the window 516 by 280 at 1440, 363 by 196 at 834 and 343
   by 185 on the phone, which is one proportion at three sizes, so the window
   keeps that proportion and only its width changes.
   
   The drawing is fitted inside the window rather than filling it. Figma's
   own source is a tall picture cropped to that window; the export we have is
   already a wider crop of the same artwork, at 1200 by 606, so filling the
   window cut the envelope on one side and the figure on the other however
   the numbers were arranged. Fitting it keeps every part of the drawing, and
   the space left over is transparent against the dark footer. */
.kv-foot__illustration .kv-picture img,
.kv-foot__illustration img {
	width: 516px; max-width: 100%; height: auto;
	aspect-ratio: 516 / 280; object-fit: contain; object-position: center;
}
/* The phone draws it the full width of the gutter and 185 tall, node 1:2136. */
/* The tablet window is 196 tall, node 1:1991. The frame draws it 363 wide,
   which would put the drawing 34 past the 80 gutter every other band keeps,
   so it ends on the margin instead. */
@media (min-width: 768px) and (max-width: 1024px) {
	.kv-foot__illustration .kv-picture img,
	.kv-foot__illustration img { width: 100%; max-width: 363px; margin-left: auto; }
}
/* The phone draws 343 by 185, node 1:2136. Between there and the tablet
   layout the window keeps that shape rather than staying 185 tall, which
   turned into a letterbox by 600. */
@media (max-width: 767px) {
	.kv-foot__illustration .kv-picture img,
	.kv-foot__illustration img { width: 100%; max-width: none; }
}

/* The consent line is Caption, node 1:1838. It is a paragraph inside a text
   editor widget, and that widget's own rule for a paragraph was winning. */
.kv-footer p.kv-foot__consent,
.kv-footer .kv-foot__consent p { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }

/* The copyright is Body 2 in Text/Disabled, node 1:1979. It sits in a text
   editor widget, whose own rule for a paragraph was winning on specificity
   and printing it at Body 1 in the page colour. */
.kv-footer .kv-foot__copy,
.kv-footer p.kv-foot__copy {
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	color: var(--kv-text-disabled); text-align: center;
}

/* Between 1025 and 1180 the 1440 header cannot fit without squeezing the search
   box to nothing, so that band uses the 834 header, which is a drawn layout
   rather than a guess. Elementor's own hide classes stop at 1024, so the swap
   happens here. */
@media (min-width: 1025px) and (max-width: 1179px) {
	.kv-header .kv-header__wide { display: none !important; }
	.kv-header .kv-header__compact,
	.kv-header .kv-header__search { display: flex !important; }
	.kv-header .kv-header__compact {
		display: grid !important;
		grid-template-columns: 1fr auto 1fr;
		align-items: center;
		padding: 16px clamp(24px, 7vw, 80px) !important;
	}
	.kv-header .kv-header__compact > :first-child { justify-self: start; }
	.kv-header .kv-header__compact > :last-child { justify-self: end; }
	.kv-header .kv-header__search { padding: 0 clamp(24px, 7vw, 80px) 20px !important; }
	.kv-header .kv-announce,
	.kv-header .kv-announce > .e-con-inner { flex-direction: row !important; height: auto; overflow: visible; }
	.kv-header .kv-announce .elementor-widget-text-editor { position: static; animation: none; width: auto; }
}

/* ---------------------------------------------------------------------------
   Badge carousel above the footer.

   The set is repeated several times and the track slides left by exactly one
   set, 100% divided by the number of copies, so when the loop restarts the
   next copy is standing where the last one began and the join cannot be seen.
   Enough copies are rendered that the track always covers the screen; two is
   not enough once a set is narrower than the viewport. Duration scales with
   the number of items so the speed stays the same if one is added.
   ------------------------------------------------------------------------ */

/* The band stands 104 at every width and on every page in the design, with
   the row of marks 32 from the top, node 1:1534. The 48 mark and those two
   numbers are the whole height. */
.kv-badges {
	background: var(--kv-primary-12);
	overflow: hidden;
	padding: 32px 0 24px;
}
.kv-badges__track {
	display: flex;
	width: max-content;
	animation: kv-badges-scroll calc(var(--kv-badges-count, 4) * 10s) linear infinite;
}
.kv-badges__set {
	display: flex;
	align-items: center;
	gap: 48px;
	list-style: none;
	margin: 0;
	/* The trailing space matches the gap between items, so the seam between the
	   two copies is spaced like every other join. It is part of the set's width,
	   which is what keeps the -50% slide landing exactly on the repeat. */
	padding: 0 48px 0 0;
}
.kv-badges__item {
	display: flex;
	align-items: center;
	gap: 16px;
	color: var(--kv-primary);
	font-size: var(--kv-fs-body1);
	line-height: 1.8;
	white-space: nowrap;
}
.kv-badges__icon { width: 48px; height: 48px; flex: 0 0 48px; }

@keyframes kv-badges-scroll {
	from { transform: translateX(0); }
	to   { transform: translateX(calc(-100% / var(--kv-badges-copies, 6))); }
}

.kv-badges:hover .kv-badges__track { animation-play-state: paused; }

/* The phone band is the same band: the frames draw it 104 tall with the same
   48 mark and the same Body 1 beside it at 375, 834 and 1440. It had been
   shrinking to 76 on a phone, which is the one size the design never uses. */

/* Movement that cannot be stopped is a problem for some people, so it holds
   still and the second copy is dropped. */
@media (prefers-reduced-motion: reduce) {
	.kv-badges__track { animation: none; }
	.kv-badges__set[aria-hidden="true"] { display: none; }
	.kv-badges { overflow-x: auto; }
}

/* ---------------------------------------------------------------------------
   Menu overlay for the compact header.

   A native <dialog>, so the backdrop, the focus trap and Escape come from the
   browser. It is positioned against the left edge rather than centred.
   ------------------------------------------------------------------------ */

dialog.kv-panel {
	margin: 0;
	padding: 0;
	border: 0;
	width: 311px;
	max-width: 85vw;
	height: 100dvh;
	max-height: 100dvh;
	inset-inline-start: 0;
	inset-block-start: 0;
	background: var(--kv-paper);
	color: var(--kv-text);
	overflow: visible;
}
dialog.kv-panel::backdrop { background: rgba(0, 0, 0, 0.4); }

.kv-panel__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 24px;
	padding: 20px 16px;
	height: 100%;
	overflow-y: auto;
	/* The panel still scrolls when the drawer is open, it just does it without
	   drawing a bar down the middle of the overlay. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}
.kv-panel__inner::-webkit-scrollbar { width: 0; height: 0; }

.kv-panel__close {
	position: absolute;
	top: 12px;
	inset-inline-end: 12px;
	width: 40px;
	height: 40px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	background: none;
	color: var(--kv-text);
	cursor: pointer;
}

/* Node 2:24172 puts a row every 48: a 24 line with 24 under it. The rows here
   are 32, because the commissioned mark beside each one carries a 32 floor, so
   the gap closes to 16 and the rhythm is the frame's. */
.kv-panel__nav > ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
/* Solid, not the secondary grey: these are the site's navigation, and a
   faded label reads as a disabled one. The current page keeps Primary. */
.kv-panel__row > a {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: var(--kv-fs-body1);
	line-height: var(--kv-lh-body1);
	color: var(--kv-text);
	text-decoration: none;
}
.kv-panel__nav .is-current .kv-panel__row > a { color: var(--kv-primary); }
.kv-panel__icon { width: 24px; height: 24px; flex: 0 0 24px; }

.kv-panel__lang .kv-lang__current { padding: 0; }
.kv-panel__lang .kv-lang__list { position: static; box-shadow: none; background: none; padding: 8px 0 0; }
.kv-panel__lang .kv-lang__list a { padding: 4px 0; }

/* The trigger only exists on the compact header, so the panel never opens on
   the desktop layout. Closing it there as well keeps the markup inert. */
@media (min-width: 1180px) {
	dialog.kv-panel[open] { display: none; }
}

/* The kit styles every button, so the close control needs to say plainly that
   it has no chrome of its own. */
.kv-panel .kv-panel__close,
.kv-panel .kv-panel__close:hover,
.kv-panel .kv-panel__close:focus {
	background: none !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	color: var(--kv-text) !important;
	padding: 0 !important;
}
.kv-panel .kv-panel__close:focus-visible { outline: 2px solid var(--kv-primary); outline-offset: 2px; }
.kv-panel .kv-panel__close .karivarah-icon { width: 24px; height: 24px; }

/* The commissioned icons carry far more line detail than the plain ones the
   frame was drawn with, so they read better a little larger. */
.kv-panel__icon { width: 28px; height: 28px; flex-basis: 28px; }
.kv-panel__row > a { gap: 12px; }

/* Panel header: logo on the left, close on the right, as the frame has it. */
.kv-panel__head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
}
.kv-panel__head .kv-logo { width: 140px; }
.kv-panel .kv-panel__close { position: static; width: 40px; height: 40px; flex: 0 0 40px; }

/* One focus style across the panel, in the brand colour rather than the
   browser's black box. */
.kv-panel a:focus-visible,
.kv-panel button:focus-visible { outline: 2px solid var(--kv-primary); outline-offset: 3px; border-radius: 2px; }
.kv-panel a:focus:not(:focus-visible) { outline: none; }

/* ---------------------------------------------------------------------------
   The Shop drawer inside the overlay.

   Measured from node 2:131358 against its 279px content column: the row and
   the first card 16px apart, cards 16px apart, 48px thumbnails on 56px rows,
   and the craft list on 20px icons at a 36px pitch.
   ------------------------------------------------------------------------ */

.kv-panel__row { display: flex; align-items: center; gap: 12px; }
.kv-panel__row > a { flex: 1 1 auto; min-width: 0; }

.kv-panel .kv-panel__caret,
.kv-panel .kv-panel__caret:hover,
.kv-panel .kv-panel__caret:focus {
	flex: 0 0 24px;
	width: 24px;
	height: 24px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0 !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	background: none !important;
	color: var(--kv-text-2) !important;
	cursor: pointer;
}
.kv-panel__caret .karivarah-icon { width: 20px; height: 20px; transition: transform 0.2s; }
.kv-panel__caret:hover { color: var(--kv-primary) !important; }

.kv-panel__drawer {
	padding: 16px 0 8px; /* 8px, so the next item sits 32px below the drawer */
}

/* The gap belongs here, not on the drawer: the drawer holds one child, this
   wrapper, and the two cards are inside it. */
.kv-drawer { display: flex; flex-direction: column; gap: 16px; }

.kv-drawer__cats {
	background: var(--kv-paper);
	border: 1px solid var(--kv-grey-600);
	border-radius: 12px;
	padding: 16px;
}
.kv-drawer__crafts {
	background: var(--kv-primary-4);
	border: 1px solid var(--kv-primary-8);
	border-radius: 12px;
	padding: 16px;
}

.kv-drawer .kv-drawer__all {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 8px;
	font-size: var(--kv-fs-body1);   /* the size the craft heading is set at */
	line-height: var(--kv-lh-body1);
	color: var(--kv-text);
	text-decoration: none;
}
.kv-drawer .kv-drawer__all:hover { color: var(--kv-primary); }

.kv-drawer__title {
	margin: 0 0 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--kv-grey-900);
	font-size: var(--kv-fs-body1);
	line-height: var(--kv-lh-body1);
	color: var(--kv-text-2);
}

.kv-drawer__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.kv-drawer .kv-drawer__list a {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: var(--kv-fs-body2);
	line-height: var(--kv-lh-body2);
	color: var(--kv-text);
	text-decoration: none;
	overflow-wrap: anywhere;
}
.kv-drawer__pic { flex: 0 0 48px; width: 48px; height: 48px; display: block; }
.kv-drawer__pic img { width: 48px; height: 48px; object-fit: contain; display: block; }

.kv-drawer__list--crafts { gap: 16px; }
.kv-drawer__list--crafts a { gap: 10px; }
.kv-drawer__icon { flex: 0 0 20px; width: 20px; height: 20px; }

/* ---------------------------------------------------------------------------
   Menu trigger: the lines change colour and nothing else.
   The kit styles `button`, `button:hover`, `button:focus` and `button:active`
   with a background and a border, and a pseudo-class outranks a plain class,
   so every state is written out.
   ------------------------------------------------------------------------ */

.kv-header .kv-menu-toggle,
.kv-header .kv-menu-toggle:hover,
.kv-header .kv-menu-toggle:focus,
.kv-header .kv-menu-toggle:active,
.kv-header .kv-menu-toggle[aria-expanded="true"] {
	background: none !important;
	background-color: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
	padding: 0 !important;
	text-shadow: none !important;
}

.kv-header .kv-menu-toggle { color: var(--kv-text) !important; }
.kv-header .kv-menu-toggle:hover,
.kv-header .kv-menu-toggle:active,
.kv-header .kv-menu-toggle[aria-expanded="true"] { color: var(--kv-primary) !important; }
.kv-header .kv-menu-toggle:focus-visible { outline: 2px solid var(--kv-primary); outline-offset: 2px; }
.kv-header .kv-menu-toggle:focus:not(:focus-visible) { outline: none; }

/* Hello Elementor paints every [type="button"] and [type="submit"] pink on
   hover and focus. The theme's own buttons say otherwise, once, here. */
.kv-signup .kv-signup__button,
.kv-signup .kv-signup__button:hover,
.kv-signup .kv-signup__button:focus,
.kv-signup .kv-signup__button:active {
	color: var(--kv-white) !important;
	border: 0 !important;
	text-decoration: none !important;
}
.kv-signup .kv-signup__button { background-color: var(--kv-primary) !important; }
@media (hover: hover) {
	.kv-signup .kv-signup__button:hover { background-color: var(--kv-primary) !important; box-shadow: var(--kv-elevation-primary) !important; }
}
.kv-signup .kv-signup__button:active { background-color: var(--kv-primary-dark) !important; box-shadow: var(--kv-elevation-primary) !important; }
.kv-signup .kv-signup__button:focus-visible { outline: 2px solid var(--kv-white); outline-offset: 2px; box-shadow: none !important; }

/* ---------------------------------------------------------------------------
   Shop dropdown.

   Hangs off the Shop item in the main menu, so the nav widget still provides
   the trigger and the caret. Elementor's own submenu for that item is hidden,
   since the panel lists the same categories with their illustrations.

   Opens on hover and on keyboard focus, and the columns are grid tracks with
   min-width 0 so long names wrap instead of widening the panel.
   ------------------------------------------------------------------------ */

.kv-header__wide { position: relative; }

.kv-nav .kv-has-shop-panel > .sub-menu,
.kv-nav .kv-has-shop-panel .elementor-nav-menu--dropdown { display: none !important; }

.kv-shop {
	position: absolute;
	top: calc(100% + 12px);
	left: 0;
	right: 0;
	z-index: 200;
	display: none;
	grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
	gap: 40px;
	padding: 24px;
	background: var(--kv-paper);
	border-radius: 16px;
	box-shadow: var(--kv-elevation-3);
	text-align: start;
	cursor: default;
}
.kv-has-shop-panel { position: static !important; }
.kv-has-shop-panel:hover > .kv-shop,
.kv-has-shop-panel:focus-within > .kv-shop { display: grid; }

/* Shop all */
.kv-shop__all {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 16px;
	font-size: var(--kv-fs-body1);
	line-height: var(--kv-lh-body1);
	color: var(--kv-text) !important;
	text-decoration: none;
}
.kv-shop__all:hover { color: var(--kv-primary) !important; }

/* Categories, two columns with room between them */
.kv-shop__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 40px;
	row-gap: 8px;
}
.kv-shop__grid > li { min-width: 0; }
.kv-shop__grid a {
	display: grid;
	grid-template-columns: 72px minmax(0, 1fr);
	align-items: center;
	gap: 16px;
	padding: 12px;
	border-radius: 12px;
	text-decoration: none;
	color: inherit;
}
/* Hover: the 8% primary tint the frame uses, node 2:132124, with the heading
   in the primary on top of it. */
.kv-shop__grid a:hover { background: var(--kv-primary-8); }
.kv-shop__grid a:hover .kv-shop__name { color: var(--kv-primary); }
.kv-shop__pic { display: block; }
.kv-shop__pic img { width: 72px; height: 72px; object-fit: contain; display: block; }
.kv-shop__text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kv-shop__name {
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
	color: var(--kv-text); overflow-wrap: break-word;
}
.kv-shop__desc {
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); overflow-wrap: break-word;
}

/* Crafts */
.kv-shop__crafts {
	background: var(--kv-primary-6);
	border-radius: 16px;
	padding: 24px;
	min-width: 0;
}
.kv-shop__crafttitle {
	margin: 0 0 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--kv-grey-900);
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2);
}
.kv-shop__craftgrid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: 24px; row-gap: 12px;
}
.kv-shop__craftgrid > li { min-width: 0; }
.kv-shop__craftgrid a {
	display: grid;
	grid-template-columns: 24px minmax(0, 1fr);
	align-items: center;
	gap: 10px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text) !important;
	text-decoration: none;
	overflow-wrap: break-word;
}
.kv-shop__craftgrid a:hover { color: var(--kv-primary) !important; }
.kv-shop__crafticon { width: 24px; height: 24px; flex: 0 0 24px; }

/* The panel belongs to the desktop header only. */
@media (max-width: 1179px) { .kv-shop { display: none !important; } }

/* The panel is positioned against the white bar, so every wrapper between the
   two has to stop being a positioning context. Elementor sets position:relative
   on containers and widgets by default, which is what made the panel size
   itself to the logo and menu group instead of the bar. */
.kv-header__wide > .kv-hgroup,
.kv-header__wide .elementor-widget-nav-menu,
.kv-header__wide .elementor-widget-container,
.kv-nav .elementor-nav-menu,
.kv-nav .elementor-nav-menu > li { position: static !important; }

/* The panel sits inside a menu item, so Elementor's menu script treats its
   lists as submenus and hides them, inline. These say otherwise. */
.kv-shop .kv-shop__grid,
.kv-shop .kv-shop__craftgrid { display: grid !important; }
.kv-shop .kv-shop__grid > li,
.kv-shop .kv-shop__craftgrid > li { display: block !important; position: static !important; }
.kv-shop .kv-shop__grid a,
.kv-shop .kv-shop__craftgrid a { display: grid !important; }

/* Elementor pads every menu anchor by 13px 20px. Inside the panel that padding
   is what set the row rhythm, not the gap, and it indented the craft icons past
   the panel heading. Rows are spaced by the grid alone.

   Hover changes the colour and nothing else, so every box property is pinned
   across the three states rather than left for Elementor to set. The line
   height is the one that moved the rows: Elementor's hover rule is
   .elementor-nav-menu a:hover, a class more specific than our plain
   .kv-shop__craftgrid a, so pointing at a row dropped it from 24px to 20px and
   the 0.4s transition on the same anchor animated the text up those 2px. */
.kv-shop .kv-shop__craftgrid a,
.kv-shop .kv-shop__craftgrid a:hover,
.kv-shop .kv-shop__craftgrid a:focus {
	font-size: var(--kv-fs-body1) !important;
	line-height: var(--kv-lh-body1) !important;
	padding: 0 !important;
	margin: 0 !important;
	border: 0 !important;
	background: none !important;
	transform: none !important;
	text-decoration: none !important;
	font-weight: var(--kv-weight) !important;
	letter-spacing: normal !important;
}

/* Elementor positions submenu lists absolutely and gives them their own width,
   shadow and background. Inside the panel they are ordinary grids. */
.kv-shop ul {
	position: static !important;
	top: auto !important; left: auto !important; right: auto !important; bottom: auto !important;
	width: auto !important; min-width: 0 !important; max-width: none !important;
	transform: none !important;
	box-shadow: none !important;
	background: none !important;
	border: 0 !important;
	margin: 0 !important;
	z-index: auto !important;
	visibility: visible !important;
	opacity: 1 !important;
}
.kv-shop .kv-shop__grid { padding: 0 !important; }

/* Same line-height trap as the crafts, on the rows that carry the images. */
.kv-shop .kv-shop__grid a,
.kv-shop .kv-shop__grid a:hover,
.kv-shop .kv-shop__grid a:focus { line-height: 24px !important; }
.kv-shop .kv-shop__craftgrid { padding: 0 !important; }

/* Menu links are nowrap by default, which is right for a nav bar and wrong
   inside the panel, where it made descriptions run across the next column. */
.kv-shop a,
.kv-shop span,
.kv-shop p { white-space: normal !important; }

/* The craft list is one column. The frame has two, but it was drawn with the
   English names: "Kurvfletting og veving" and "Skulptur og treskjæring" do not
   fit two to a 380px panel without breaking mid-word. */
.kv-shop .kv-shop__craftgrid { grid-template-columns: minmax(0, 1fr); row-gap: 12px; }
.kv-shop__craftgrid a { align-items: start; }
.kv-shop__craftgrid span { padding-top: 1px; }

/* ---------------------------------------------------------------------------
   Keeping the panel open on the way to it.

   The Shop link ends 53px above the panel, so a pointer travelling down leaves
   the menu item and the panel closes before it can be reached. This extends the
   link's hover area across that gap, and no further: it is the width of the
   link plus a little, so it never sits over the search box beside it.

   Once the pointer is on the panel, hover is held by the panel being inside the
   same list item, so nothing more is needed.
   ------------------------------------------------------------------------ */

.kv-nav .kv-has-shop-panel > .elementor-item { position: relative; }
.kv-nav .kv-has-shop-panel > .elementor-item::after {
	content: "" !important;
	display: block !important;
	position: absolute;
	left: -16px;
	right: -16px;
	top: -8px;
	bottom: -56px;
	background: none;
	pointer-events: auto;
}
/* While the panel is closed the extension would swallow clicks meant for what
   is underneath, so it only exists on the way in. */
.kv-nav .kv-has-shop-panel:not(:hover):not(:focus-within) > .elementor-item::after { display: none !important; }

/* ---------------------------------------------------------------------------
   Shop panel geometry, measured off the frame rather than guessed.

   Panel 1136 wide, which is the site's content width, not the full window.
   Inside: 650 for the categories, 8px, 454 for the crafts, on 12px padding.
   Category rows are 313 wide in two columns 24px apart, each an 80px image,
   8px, then the text. The craft grid is two 195px columns 16px apart.
   ------------------------------------------------------------------------ */

.kv-header__wide { --kv-bar-gutter: 152px; }
@media (min-width: 1180px) and (max-width: 1439px) {
	.kv-header__wide { --kv-bar-gutter: clamp(24px, 10.5vw, 152px); }
}

.kv-shop {
	left: var(--kv-bar-gutter);
	right: var(--kv-bar-gutter);
	grid-template-columns: minmax(0, 650fr) minmax(0, 454fr);
	gap: 8px;
	padding: 12px;
}

.kv-shop__cats { padding: 12px; }
.kv-shop__all { margin-bottom: 24px; }

.kv-shop__grid { column-gap: 24px; row-gap: 12px; }
.kv-shop__grid a { grid-template-columns: 80px minmax(0, 1fr); gap: 8px; padding: 0; border-radius: 8px; }
.kv-shop__pic img { width: 80px; height: 80px; }
.kv-shop__name { font-size: var(--kv-fs-body1); font-weight: var(--kv-weight-semibold); }
.kv-shop__desc { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

/* Beside the categories the craft box is as tall as all three category rows,
   so the list fills it and the rows space themselves across that height. The
   two columns then start and finish together. */
.kv-shop__crafts { padding: 24px; border-radius: 12px; display: flex; flex-direction: column; }
.kv-shop__crafttitle { margin: 0 0 20px; padding-bottom: 20px; font-size: var(--kv-fs-body1); }
/* One column at every width. The frame has two, drawn with the English labels,
   but the Norwegian names wrap at that measure and a single column reads
   better than a ragged pair. */
.kv-shop .kv-shop__craftgrid {
	grid-template-columns: minmax(0, 1fr);
	row-gap: 12px;
	flex: 1 1 auto;
	align-content: space-between;
}

/* The hover bridge must never be seen. Elementor's pointer styling paints
   .elementor-item::after, which is the element being borrowed here. */
.kv-nav .kv-has-shop-panel > .elementor-item::after {
	background: none !important;
	background-color: transparent !important;
	background-image: none !important;
	border: 0 !important;
	box-shadow: none !important;
	opacity: 1 !important;
	transform: none !important;
	transition: none !important;
}

/* ---------------------------------------------------------------------------
   Diagonal arrows straighten on hover.

   Site-wide: wherever the up-right arrow appears next to a link, hovering or
   focusing that link rotates it 45 degrees so it points right. Written against
   the icon's own class, so it applies to anything using it without each new
   component repeating the rule.
   ------------------------------------------------------------------------ */

.karivarah-icon--arrow-up-right { transition: transform .2s ease; }

a:hover .karivarah-icon--arrow-up-right,
a:focus-visible .karivarah-icon--arrow-up-right,
button:hover .karivarah-icon--arrow-up-right,
button:focus-visible .karivarah-icon--arrow-up-right,
summary:hover .karivarah-icon--arrow-up-right { transform: rotate(45deg); }

/* The external arrow sits in a box, so it cannot rotate without the box
   tilting with it. It travels the same direction instead, at one pixel. */

.karivarah-icon--arrow-square-out { transition: transform .2s ease; }

a:hover .karivarah-icon--arrow-square-out,
a:focus-visible .karivarah-icon--arrow-square-out,
.kv-bcard:hover .karivarah-icon--arrow-square-out { transform: translate(1px, -1px); }

@media (prefers-reduced-motion: reduce) {
	.karivarah-icon--arrow-up-right,
	.karivarah-icon--arrow-square-out { transition: none; }
}

/* ---------------------------------------------------------------------------
   Shop page, node 2:23098, and the sections it shares with the home and
   product pages. Measured against the 1136 content column at 1440.
   ------------------------------------------------------------------------ */

.kv-main {
	max-width: 1440px;
	margin: 0 auto;
	padding: 100px var(--kv-gutter) 0;
}

/* Breadcrumbs */
/* The trail, nodes 2:23255 at 1440 and 834 and 2:23577 at 375. The crumbs sit
   4px apart, not 8, and step from Body 1 to Body 2 on a phone. */
.kv-crumbs {
	display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}
.kv-crumbs a { color: var(--kv-text-2); text-decoration: none; }
.kv-crumbs [aria-current] { color: var(--kv-primary); }
/* The separator is the same grey as the crumb beside it, Text/Secondary. It
   had been the disabled grey, which is a step lighter than anything in the
   frame. Measured off the exported mark: stroke #6A6A6A at 24px, 20 on a
   phone. */
.kv-crumbs__sep { width: 24px; height: 24px; flex: 0 0 24px; color: var(--kv-text-2); }

/* Browse cards, node 2:23115 */
.kv-cards { margin: 0; }
.kv-cards .kv-crumbs { margin-bottom: 24px; }
.kv-cards__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
/* 24 between the heading and the line under it, node I2:22437;18323:59586. */
.kv-cards__words { display: flex; flex-direction: column; gap: 24px; }
.kv-cards__intro { margin: 0; }
/* Two classes deep: Elementor's kit sets `h1` at 48 with a class and an
   element, which beats a bare class however late it comes. The page heading
   happened to be 48 at 1440 as well, so the rule looked right until the
   phone, where it should be 32. */
.kv-cards .kv-cards__heading { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1); color: var(--kv-text); }
h2.kv-cards__heading { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }

/* At 1024 and below every arrow is resized by a rule in the home page's
   1024px block, marked "Site-wide". */
.kv-arrows { display: flex; gap: 8px; flex: 0 0 auto; }
.kv-arrow,
.kv-arrow:hover,
.kv-arrow:focus {
	width: 32px; height: 32px; flex: 0 0 32px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important;
	color: var(--kv-text) !important; cursor: pointer;
}
.kv-arrow:hover { color: var(--kv-primary) !important; }
.kv-arrow[disabled] { color: var(--kv-text-disabled) !important; cursor: default; }
.kv-arrow .karivarah-icon { width: 24px; height: 24px; }
.is-static .kv-arrows,
.is-static .kv-cards__dots { display: none; }

.kv-cards__track {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 380px;
	gap: 24px;
	margin-top: 64px;
	/* The row is cut by the screen, not by the content column, so the fourth
	   card shows a third of itself and says there is more to the right. The
	   distance from the column to the screen's edge is the gutter up to 1440,
	   and half of whatever the screen has beyond the 1136 column above it; a
	   gutter alone stopped the row at the 1440 shell on a wide screen. 100vw
	   counts a classic (Windows) scrollbar, so the row reaches 8px under it;
	   the parent theme's `body { overflow-x: clip }` (Hello Elementor,
	   reset.css) keeps that from becoming a sideways scroll. Tested with a
	   16px scrollbar, 15.10.2026. */
	--kv-to-edge: max(var(--kv-gutter), calc((100vw - 1136px) / 2));
	margin-right: calc(-1 * var(--kv-to-edge));
	/* and the last card stops at the content margin rather than the glass */
	padding-right: var(--kv-to-edge);
	overflow-x: auto;
	overflow-y: hidden;   /* overflow-x alone makes the y axis scrollable too */
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	overscroll-behavior-x: contain;
}
.kv-cards__track::-webkit-scrollbar { width: 0; height: 0; }

.kv-tcard {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 16px;
	/* Top, not centre. The frame's card is exactly full at two lines of name
	   and two of description; centring it meant a one-line name sat lower than
	   a two-line one beside it, and the row of names stopped being a row. */
	justify-content: flex-start;
	min-height: 176px;   /* the frame's height; longer card text may grow it */
	padding: 24px;
	border-radius: 12px;
	background: var(--kv-primary-8);
	overflow: hidden;
	scroll-snap-align: start;
	text-decoration: none;
	color: var(--kv-text);
}
.kv-tcard__text { display: flex; flex-direction: column; gap: 12px; width: calc(100% - 150px); max-width: 225px; }
.kv-tcard .kv-tcard__name { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-tcard__desc {
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2);
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* The link sits on the floor of the card, not under the words. A one line
   name used to pull it up, so the row of links wandered; the cards are all
   the same height in their row, so pushing it down lands them on one line. */
.kv-tcard .kv-tcard__cta {
	display: inline-flex; align-items: center; gap: 6px; margin-top: auto;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-tcard__cta .karivarah-icon { width: 24px; height: 24px; }
.kv-tcard__pic {
	position: absolute; right: -8px; top: 50%; transform: translateY(-50%);
	width: 180px; height: 160px;
	pointer-events: none;
}
.kv-tcard__pic img { width: 100%; height: 100%; object-fit: contain; object-position: center right; }
.kv-tcard:hover .kv-tcard__name { color: var(--kv-primary); }

.kv-cards__dots { display: flex; justify-content: center; gap: 8px; margin-top: 64px; }
/* The reviews row keeps its dots close: they sit inside the card block there,
   node 2:22455, with the call to action 64 below them. */
/* The carousel block is 384 tall in the frames, nodes 2:22455 and 2:23231:
   the cards, 24, the dots, and 24 below them. Where a button follows, that 24
   collapses into the button's own margin and the larger of the two wins. */
.kv-reviews .kv-cards__dots { margin-top: 24px; margin-bottom: 24px; }
.kv-dot,
.kv-dot:hover,
.kv-dot:focus {
	width: 12px; height: 12px; padding: 0 !important; border: 0 !important;
	border-radius: 100px !important; box-shadow: none !important;
	background: var(--kv-grey-900) !important; cursor: pointer;
}
.kv-dot.is-on { background: var(--kv-primary) !important; }

/* The shop's masthead, node 2:23114. The browse cards sit closer to the
   heading here than they do in a band on the home page: 48 under the title
   row and the dots 24 under the cards, where a home page band has 64 for
   both. */
.kv-shoppage .kv-cards__track { margin-top: 48px; }
.kv-shoppage .kv-cards__dots { margin-top: 24px; }

/* Filter and sort bar */
.kv-shoppage__bar { display: flex; align-items: flex-start; justify-content: space-between; gap: 24px; margin-top: 48px; }
/* An archive heading stands 64 clear of the bar where the shop stands 48:
   nodes 2:23253 and 2:23266 against 2:23115 and 2:23182. */
@media (min-width: 1025px) {
	.kv-main:has(> .kv-termhead) .kv-shoppage__bar { margin-top: 64px; }
}
.kv-filters { display: flex; flex-wrap: wrap; gap: 20px; }

/* The trigger, node 1:2731: a Grey/200 pill, Subheading 1 on a 24 caret, 16
   of padding on the words side and 12 on the caret's, and 12 above and below
   the line, which is the 48 the frame draws. */
.kv-filter { position: relative; }
.kv-filter > summary {
	display: inline-flex; align-items: center; gap: 4px;
	height: 48px; padding: 0 12px 0 16px;
	border-radius: 100px; background: var(--kv-grey-200);
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text);
	cursor: pointer; list-style: none; white-space: nowrap;
}
.kv-filter > summary .karivarah-icon { width: 24px; height: 24px; }
/* Open, the pill takes a stroke in the ink colour, node 1:2737. It comes out
   of the padding so the pill stays 48. */
.kv-filter[open] > summary {
	border: 1px solid var(--kv-text); padding: 0 11px 0 15px; height: 48px;
}
.kv-filter > summary::-webkit-details-marker { display: none; }
.kv-filter.is-active > summary { background: var(--kv-primary-8); color: var(--kv-primary); }
.kv-filter[open] > summary .karivarah-icon { transform: rotate(180deg); }
/* The sort trigger carries no pill, node 1:2434: the words at Body 1 and the
   caret beside them. */
.kv-sort .kv-filter > summary {
	background: none; padding: 0; height: auto; border: 0;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}
.kv-sort .kv-filter[open] > summary { border: 0; padding: 0; }

/* The panel, node 1:2577: 266 wide, 16 of padding, its rows 16 apart, no
   stroke, and Elevation 4 under it. It opens 8 below the pill, which is the
   frame's 56 from the top of the trigger. */
.kv-filter__panel {
	position: absolute; z-index: 20; top: calc(100% + 8px); left: 0;
	/* As tall as it needs to be, the way the frame draws it. A cap is kept
	   for something unexpectedly long, but 320 cut the origin list at eight
	   entries and put a scrollbar through a panel that fits. */
	width: 266px; max-height: min(70vh, 640px); overflow-y: auto;
	display: flex; flex-direction: column; gap: 16px;
	padding: 16px; border-radius: 12px;
	background: var(--kv-paper); border: 0;
	box-shadow: var(--kv-elevation-4);
}
.kv-sort .kv-filter__panel { left: auto; right: 0; }
.kv-filter__opt {
	display: flex; align-items: center; justify-content: space-between; gap: 12px;
	padding: 8px 12px; border-radius: 8px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text) !important; text-decoration: none;
}
.kv-filter__opt:hover { background: var(--kv-grey-300); }
.kv-filter__opt.is-on { color: var(--kv-primary) !important; }
/* The one tick the frames draw is the one in the sort list, and it is green,
   node I1:2339;1:2832. */
.kv-filter__tick { color: var(--kv-success); width: 20px; height: 20px; }
.kv-filter__count { color: var(--kv-text-2); }

/* A long list of attributes runs in two columns, node 1:2630, rather than
   scrolling: the panel widens to 516 and the rows fill the first column
   before starting the second. */
.kv-filter__panel--two {
	display: block; width: 516px; max-height: none;
	columns: 2; column-gap: 16px;
}
.kv-filter__panel--two .kv-filter__opt { break-inside: avoid; margin-bottom: 16px; }

/* The price slider, node 1:2556: the chosen stretch in the ink colour on a
   Grey Primary/400 rail, and two 16 handles with a white edge. The inputs
   are stacked on the rail and only their handles take the pointer, so the
   one underneath is still reachable. */
.kv-prange { display: flex; flex-direction: column; gap: 8px; }
.kv-prange__nums {
	display: flex; justify-content: space-between;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-prange__track { position: relative; height: 16px; }
.kv-prange__rail,
.kv-prange__fill {
	position: absolute; top: 50%; transform: translateY(-50%);
	height: 4px; border-radius: 10px;
}
.kv-prange__rail { left: 0; right: 0; background: var(--kv-grey-primary-400); }
.kv-prange__fill { background: var(--kv-text); }
.kv-prange__in {
	position: absolute; left: 0; top: 0; width: 100%; height: 16px; margin: 0;
	appearance: none; -webkit-appearance: none; background: none; pointer-events: none;
}
.kv-prange__in:focus { outline: none; }
.kv-prange__in::-webkit-slider-thumb {
	-webkit-appearance: none; appearance: none;
	width: 16px; height: 16px; border-radius: 100px;
	background: var(--kv-text); border: 1px solid var(--kv-paper);
	pointer-events: auto; cursor: pointer;
}
.kv-prange__in::-moz-range-thumb {
	width: 16px; height: 16px; border-radius: 100px;
	background: var(--kv-text); border: 1px solid var(--kv-paper);
	pointer-events: auto; cursor: pointer;
}
.kv-prange__in:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--kv-primary); outline-offset: 2px; }
.kv-prange__in:focus-visible::-moz-range-thumb { outline: 2px solid var(--kv-primary); outline-offset: 2px; }
/* The price panel is the one with room above and below the track, node
   1:2550. */
.kv-filter__panel:has(.kv-prange) { padding: 32px 16px; }

/* An attribute row is a box and a label, node 1:2578: no padding of its own,
   8 between the box and the words, and the panel's gap does the spacing. */
.kv-filter__opt--box {
	justify-content: flex-start; gap: 8px;
	padding: 0; border-radius: 0;
}
.kv-filter__opt--box:hover { background: none; }
.kv-filter__opt--box.is-on { color: var(--kv-text) !important; }
.kv-filter__opt--box .kv-fbox { flex: 0 0 20px; width: 20px; height: 20px; margin-top: 0; }

/* The sort list is its own shape, node 1:2338: 200 wide on an 8 radius, rows
   that carry their own padding, and the chosen one on Grey/200. */
.kv-sort .kv-filter__panel { width: 200px; padding: 0; gap: 0; border-radius: 8px; }
.kv-sort .kv-filter__opt { padding: 8px 16px; border-radius: 0; }
/* Hover and chosen wear the same Grey/200, node 1:2826: the tick is what
   tells them apart. */
.kv-sort .kv-filter__opt:hover { background: var(--kv-grey-200); }
.kv-sort .kv-filter__opt.is-on { background: var(--kv-grey-200); color: var(--kv-text) !important; }

.kv-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-top: 24px; }
.kv-pill {
	display: inline-flex; align-items: center; gap: 8px;
	height: 40px; padding: 0 16px;
	border: 1px solid var(--kv-grey-900); border-radius: 100px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text) !important; text-decoration: none;
}
.kv-pill:hover { border-color: var(--kv-primary); color: var(--kv-primary) !important; }
.kv-pills__clear { font-weight: var(--kv-weight-semibold); color: var(--kv-text) !important; text-decoration: none; }
.kv-pills__clear:hover { color: var(--kv-primary) !important; }

.kv-results { margin: 24px 0 32px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }

/* The grid */
.kv-grid {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
	column-gap: 24px; row-gap: 36px;
}
/* Nothing matched. Drawn as the empty cart is, node 2:35112: a commissioned
   mark in a circle, then the sentence. */
.kv-empty { display: flex; flex-direction: column; align-items: center; gap: 24px; margin: 48px 0 96px; text-align: center; color: var(--kv-text-2); }
.kv-empty__mark { display: grid; place-items: center; padding: 24px; border-radius: 1000px; background: var(--kv-primary-4); color: var(--kv-primary-light); }
.kv-empty__mark .karivarah-icon { width: 64px; height: 64px; }
.kv-empty p { margin: 0; max-width: 416px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
@media (max-width: 767px) {
	.kv-empty { gap: 16px; margin: 32px 0 64px; }
	.kv-empty__mark { padding: 16px; }
	.kv-empty__mark .karivarah-icon { width: 48px; height: 48px; }
	.kv-empty p { max-width: 247px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
}

/* The product card, node 2:23200 */
.kv-card { position: relative; }
.kv-card__link { display: flex; flex-direction: column; gap: 16px; text-decoration: none; color: inherit; }
.kv-card__media {
	position: relative; display: block;
	aspect-ratio: 1 / 1; border-radius: 8px; overflow: hidden;
	background: var(--kv-grey-400);
}
.kv-card__img {
	position: absolute; inset: 0;
	width: 100%; height: 100%; object-fit: cover; display: block;
	transition: opacity 0.3s ease;
}
.kv-card__img--back { opacity: 0; }
/* The photo laid on the tile: its white becomes the tile's grey, so a card on
   white stands apart from the white page (karivarah_card_is_tinted(), two
   switches, 16.10.2026). The files are untouched. */
.kv-card--tint .kv-card__img { mix-blend-mode: multiply; }
/* The product page's main photo and thumbnails, by the same two switches
   (the client, 16.10.2026). Their frames are already the tile grey. The zoom
   view is left alone: it shows the photo as it is, on its dark backdrop. */
.kv-pdp__gallery--tint .kv-pdp__frame img,
.kv-pdp__gallery--tint .kv-pdp__thumb img { mix-blend-mode: multiply; }
/* A multiplied picture blends with whatever is under it, so on hover the
   second photo was laid over the first and both showed (the client,
   16.10.2026). The first one fades out as the second fades in, so each is
   only ever laid on the tile. Only where there is a second photo. */
.kv-card--tint:hover .kv-card__media:has(.kv-card__img--back) .kv-card__img--front { opacity: 0; }
.kv-card:hover .kv-card__img--back { opacity: 1; }
.kv-card.is-sold-out .kv-card__media::after {
	content: ""; position: absolute; inset: 0; border-radius: 8px;
	background: var(--kv-overlay-white-60); pointer-events: none;
}

/* Above the wash. The overlay is generated as the last child of the media, so
   in painting order it came after the tags and faded the one word that says
   why the picture is faded. A stacking order of its own lifts the tags clear,
   and nothing else in the media asks for one. */
.kv-card__tags {
	position: absolute; left: 8px; bottom: 12px; z-index: 1;
	display: flex; flex-direction: column-reverse; align-items: flex-start; gap: 4px;
}
.kv-tag {
	display: inline-flex; align-items: center;
	padding: 6px 8px; border-radius: 4px;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text);
	background: var(--kv-grey-200);
	white-space: nowrap;
}
.kv-tag--unique { background: rgba(249, 226, 143, 0.85); }
.kv-tag--new { background: var(--kv-text); color: var(--kv-grey-100); }
.kv-tag--fast { background: var(--kv-grey-100); }
.kv-tag--sold-out { background: var(--kv-paper); }
/* Off palette: #9FA5EF is in neither the style guide nor any frame. Left as
   found, pending a colour for this tag from the design. */
.kv-tag--kids { background: #9FA5EF; }

.kv-card__body { display: flex; flex-direction: column; gap: 12px; }
.kv-card .kv-card__title {
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text);
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.kv-card:hover .kv-card__title { color: var(--kv-primary); }

/* The medium card, node 1:3617: 214 wide, the name a step down at Body 1 and
   the mark 12 in from the corner rather than 16. Everything else, the 16 under
   the picture, the 12 inside the words and the badge rail 8 from the left and
   12 from the foot, is what the large card does. */
@media (min-width: 768px) and (max-width: 1024px) {
	.kv-card .kv-card__title { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	.kv-card .kv-card__wish { top: 8px; right: 8px; }
}

.kv-price { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-price__now { color: var(--kv-text); }
.kv-price--sale .kv-price__now { color: var(--kv-primary); }
.kv-price__was { color: var(--kv-text-2); text-decoration: line-through; }
/* The saving sits in the same wrapping row as the two prices, node 1:3526,
   and drops to a line of its own only when there is no room for it. It had
   been forced onto its own line whether there was room or not. */
.kv-price__save { font-weight: var(--kv-weight-semibold); color: var(--kv-primary); }
.kv-price .woocommerce-Price-amount { font: inherit; color: inherit; }

/* The frame puts the mark itself 16 from the top and the right, node 1:3527,
   and the mark is 32. The button around it is 40 so there is something to
   tap, which means the button sits 12 out and the mark lands on 16. */
.kv-card__wish,
.kv-card__wish:hover,
.kv-card__wish:focus {
	position: absolute; top: 12px; right: 12px;
	width: 40px; height: 40px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important;
	color: var(--kv-text) !important; cursor: pointer;
}
.kv-card__wish .karivarah-icon { width: 32px; height: 32px; }
.kv-card__wish:focus:not(:focus-visible) { outline: 0 !important; }
.kv-card__wish:focus-visible { outline: 2px solid var(--kv-primary) !important; outline-offset: 2px; }
.kv-card__wish:hover { color: var(--kv-primary) !important; }
/* The heart is the brand's own outline mark, so saving a piece fills it in
   rather than swapping one icon for another: the silhouette underneath takes
   the colour and the drawn line stays on top of it. */
.kv-heart__fill { fill: none; }
/* The same 1.5 the heart file carries, since the wishlist heart is rebuilt
   from the path data and never sees the file's own attributes. */
.kv-heart__line { fill: currentColor; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
[aria-pressed="true"] .kv-heart__fill { fill: var(--kv-primary); }
/* The drawing is sent once per page as a sprite symbol and referenced
   wherever it repeats, and no selector can reach inside a `<use>`. So the
   state sets an inherited custom property on the icon, which does cross. The
   two rules above still dress the inline copy that the AJAX fragments
   carry, so both forms look the same. */
.kv-heart { --kv-heart-fill: none; --kv-heart-line: currentColor; }
[aria-pressed="true"] .kv-heart { --kv-heart-fill: var(--kv-primary); }


/* Pagination, node 2:23224 */
.kv-pages { display: flex; justify-content: center; gap: 4px; margin: 48px 0 0; }
.kv-page,
.nav-links .page-numbers {
	display: inline-flex; align-items: center; justify-content: center;
	width: 48px; height: 48px; border-radius: 4px;
	background: var(--kv-grey-300); color: var(--kv-text) !important;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); text-decoration: none;
}
.kv-page:hover,
.nav-links .page-numbers:hover { background: var(--kv-primary-8); color: var(--kv-primary) !important; }
.kv-page.is-current,
.nav-links .page-numbers.current { background: var(--kv-primary); color: var(--kv-paper) !important; }
.kv-page.is-dots,
.nav-links .page-numbers.dots { background: none; }
.kv-page .karivarah-icon { width: 24px; height: 24px; }

/* WordPress writes its own classes on the blog archive's pagination, so that
   row joins the tiles above rather than restating them. */
.nav-links { display: flex; justify-content: center; gap: 4px; }

/* Payment, shipping and returns, node 2:23225 */
.kv-trust { margin-top: 100px; padding: 64px var(--kv-gutter); background: var(--kv-primary-4); }
.kv-trust__inner { max-width: 1136px; margin: 0 auto; display: flex; align-items: flex-start; gap: 48px; }
/* The frame spaces the mark from the words by 24 and the heading from the
   line under it by 16, node 2:22418, which one gap on the column cannot do.
   The column carries the 16 and the mark gives back the other 8. */
.kv-trust__col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.kv-trust__icon { margin-bottom: 8px; }
.kv-trust__icon {
	display: inline-flex; padding: 20px; border-radius: 100px;
	background: var(--kv-primary-8); color: var(--kv-primary);
}
.kv-trust__icon .karivarah-icon { width: 80px; height: 80px; }
.kv-trust .kv-trust__head { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text); }
.kv-trust__body { margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2); }

/* Customer reviews, node 2:23226 */
.kv-reviews { padding: 100px var(--kv-gutter); }
.kv-reviews__head { max-width: 1136px; margin: 0 auto 64px; text-align: center; }
.kv-reviews .kv-reviews__head h2 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-reviews__head p { margin: 24px 0 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-reviews__row { position: relative; max-width: 1136px; margin: 0 auto; }
.kv-reviews__row .kv-arrows { position: absolute; inset: 0; justify-content: space-between; align-items: center; pointer-events: none; }
.kv-reviews__row .kv-arrow {
	position: relative; pointer-events: auto;
	width: 48px !important; height: 48px !important; flex-basis: 48px;
	background: var(--kv-grey-300) !important;
}
.kv-reviews__row [data-kv-prev] { margin-left: -88px; }
.kv-reviews__row [data-kv-next] { margin-right: -88px; }
.kv-reviews__track {
	display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 28px) / 2); gap: 28px;
	overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none;
}
.kv-reviews__track::-webkit-scrollbar { width: 0; height: 0; }
/* The card, node 1:4221: Primary at eight per cent on a 16 radius, 32 of
   padding, and 24 between what was said and who said it. */
.kv-review {
	scroll-snap-align: start;
	display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 24px;
	margin: 0; padding: 32px; border-radius: 16px;
	background: var(--kv-primary-8);
	text-align: center;
}
/* The stars, the heading and the review itself, 16 apart, node 1:4223. */
.kv-review__said { display: flex; flex-direction: column; align-items: center; gap: 16px; width: 100%; }
/* The name and the verified line, 8 apart in a block 56 tall, node 1:4238. */
.kv-review__who { display: flex; flex-direction: column; align-items: center; gap: 8px; height: 56px; }
/* Stars, everywhere they appear. The mark is a solid shape, so the outline is
   a stroke on it: drawn first and then covered by the fill, which keeps the
   line even and stops it eating the hand-drawn points. An unearned star keeps
   the outline and loses the fill. */
/* The row of stars has no gap of its own, node 1:4224: the glyphs carry
   their own spacing and a gap pulled them apart. */
.kv-stars { display: inline-flex; }
.kv-star { display: inline-flex; }
.kv-star .karivarah-icon { width: 24px; height: 24px; }
.kv-star .kv-star__body {
	fill: none; stroke: var(--kv-text); stroke-width: 14;
	stroke-linejoin: round; paint-order: stroke;
}
.kv-star.is-on .kv-star__body { fill: var(--kv-secondary); }
/* The three marks are strokes, not shapes to colour in: they stay dark
   whether the star is earned or not. */
.kv-star .kv-star__marks { fill: var(--kv-text); stroke: none; }
/* Same as the heart: the star is one symbol referenced many times, so its
   colours arrive as inherited custom properties. The three rules above stay
   for the inline copy. */
.kv-star, .kv-rate__star { --kv-star-body: none; --kv-star-stroke: var(--kv-text); --kv-star-marks: var(--kv-text); }
.kv-star.is-on { --kv-star-body: var(--kv-secondary); }
/* Two classes deep, because the figcaption reset above is a class and an
   element and was winning: the heading had been printing at body size. */
.kv-review .kv-review__title { font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-review__body { margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2); }
.kv-review__name { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-review__verified { display: inline-flex; align-items: center; gap: 4px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-success-text); }
.kv-review__verified .karivarah-icon { width: 24px; height: 24px; }

/* -------------------------------------------------------------------------
   Order confirmation, nodes 128:132911 (1440), 130:133402 (834) and
   131:133819 (375). Our half of the page; Kustom's block prints under it.
   ------------------------------------------------------------------------- */

.kv-conf {
	display: flex; flex-direction: column; gap: 64px; align-items: flex-start;
	/* 1136 of content inside the gutters, not 1136 including them. */
	max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter) 64px;
}
.kv-conf__words { display: flex; flex-direction: column; gap: 24px; max-width: 592px; }
/* Two classes deep: the kit sets `h1` and `h2` with a class and an element. */
.kv-conf .kv-conf__title {
	margin: 0; font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text);
}
.kv-conf__lead {
	margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text);
}

/* The card, node 139:135044 */
.kv-conf__card {
	width: 100%; max-width: 592px;
	padding: 32px; border-radius: 24px; background: var(--kv-primary-8);
}
.kv-conf__form { display: flex; flex-direction: column; align-items: center; gap: 32px; }
.kv-conf .kv-conf__h {
	margin: 0; text-align: center; font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text);
}
.kv-conf__help,
.kv-conf__legal { margin: 0; text-align: center; color: var(--kv-text); }
.kv-conf__help { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-conf__legal { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
.kv-conf__error { margin: 0; text-align: center; color: var(--kv-error-dark); font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

/* The question sits above the stars with the gap the card gives it, and the
   helper line belongs to the stars rather than to the field below. */
.kv-conf__form .kv-rate { margin-top: -12px; }
.kv-conf__form .kv-field { width: 100%; }
/* The contact form's checks: 12px apart, and the privacy sentence, which has
   no box, starts where a box's words start (16px box plus its 8px gap). */
.kv-conf__checks { width: 100%; display: flex; flex-direction: column; gap: 12px; }
.kv-conf__checks .kv-conf__legal { text-align: left; padding-left: 24px; }
.kv-conf__form .kv-btn { align-self: center; }

/* The stars as a control. They are printed five down to one, so a checked
   star fills every star after it, which with the row reversed is every star
   to its left. The same trick draws the hover preview. */
.kv-rate { display: flex; flex-direction: row-reverse; justify-content: center; gap: 0; border: 0; margin: 0; padding: 0; }
.kv-rate__input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.kv-rate__star { display: inline-flex; cursor: pointer; padding: 0; }
.kv-rate__star .karivarah-icon { width: 48px; height: 48px; }
.kv-rate__input:checked + .kv-rate__star .kv-star__body,
.kv-rate__input:checked ~ .kv-rate__star .kv-star__body,
.kv-rate__star:hover .kv-star__body,
.kv-rate__star:hover ~ .kv-rate__star .kv-star__body { fill: var(--kv-secondary); }
/* On the star inside the label, not the label: the inner .kv-star resets the
   colour to none for itself, so a colour set one level up never reached the
   drawing and a chosen star stayed empty. */
.kv-rate__input:checked + .kv-rate__star .kv-star,
.kv-rate__input:checked ~ .kv-rate__star .kv-star,
.kv-rate__star:hover .kv-star,
.kv-rate__star:hover ~ .kv-rate__star .kv-star { --kv-star-body: var(--kv-secondary); }
.kv-rate__input:focus-visible + .kv-rate__star { outline: 2px solid var(--kv-primary); outline-offset: 2px; border-radius: 8px; }

/* Once it has been answered */
.kv-conf__card--done { display: flex; flex-direction: column; align-items: center; gap: 24px; text-align: center; }
.kv-conf__thanks { margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }

/* Kustom's own block, which follows ours */
.woocommerce-order #klarna-checkout-container,
.woocommerce-order .kco-confirmation { max-width: 1136px; margin: 0 auto 64px; padding: 0 var(--kv-gutter); }

@media (max-width: 1179px) {
	.kv-conf { gap: 48px; padding-top: 64px; }
	/* Node 130:133407: the words hold 527 and the card 410 at 834; both run
	   the column on a phone, nodes 131:133826 and 131:133831. */
	.kv-conf__card { max-width: 410px; }
	.kv-conf__words { max-width: 527px; gap: 20px; }
	.kv-conf .kv-conf__title { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
}

@media (max-width: 767px) {
	.kv-conf { gap: 24px; padding-top: 48px; }
	.kv-conf__words { gap: 16px; }
	.kv-conf__card { padding: 24px; border-radius: 16px; }
	.kv-conf__form { gap: 24px; }
	.kv-conf__checks { margin-top: 8px; } /* 32px under the message, as on the contact form at every width. */
	.kv-conf__card,
	.kv-conf__words { max-width: none; }
	.kv-conf .kv-conf__title { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
	.kv-conf .kv-conf__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-rate__star .karivarah-icon { width: 40px; height: 40px; }
	.kv-conf__form .kv-btn { width: 100%; }
}

/* Sitemap, node 2:23243 */
.kv-sitemap { padding: 100px var(--kv-gutter); background: var(--kv-primary-4); display: flex; flex-direction: column; gap: 48px; }
.kv-sitemap__group { max-width: 1136px; margin: 0 auto; width: 100%; }
.kv-sitemap .kv-sitemap__group h2 { margin: 0 0 36px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text); }
.kv-sitemap__list { list-style: none; margin: 0; padding: 0; columns: 4; column-gap: 24px; }
.kv-sitemap__list li { break-inside: avoid; margin-bottom: 16px; }
.kv-sitemap__list a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text) !important; text-decoration: none; }
.kv-sitemap__list a:hover { color: var(--kv-primary) !important; }
.kv-sitemap__count { color: var(--kv-text-2); }

/* Tablet */
@media (max-width: 1024px) {
	.kv-main { padding-top: 64px; }
	.kv-cards .kv-cards__heading { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
	.kv-cards h2.kv-cards__heading { font-size: 32px; line-height: 44px; }
	/* The card keeps its 380 at 834, node 2:24296: one whole card from the
	   gutter and the next one running off the edge, 24 apart. */
	.kv-cards__track { grid-auto-columns: 380px; gap: 24px; margin-top: 48px; }
	.kv-cards__dots { margin-top: 64px; }
	/* Three across at 834, with the gaps the frame measures: cards at 0, 230
	   and 460, each 214, so 16 between them, and rows 342 tall 366 apart, so
	   24 under each one. Nodes 2:24881 to 2:24897. */
	.kv-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 16px; row-gap: 24px; }
	/* The count sits 24 above the grid from 1024 down, nodes 2:24879 and
	   2:24957, where 1440 gives it 32. */
	.kv-results { margin-bottom: 24px; }
	/* Four filters and the sort have 674 to share at 834, so the rail closes
	   from 20 to 12, node 2:24945. */
	.kv-filters { gap: 12px; }
	/* The tablet band, node 2:24271: 48 above and below, columns 32 apart, an
	   80 circle on a 48 mark, and the heading a step down at H6. */
	.kv-trust { padding: 48px var(--kv-gutter); }
	.kv-trust__inner { gap: 32px; }
	.kv-trust__icon { padding: 16px; }
	.kv-trust__icon .karivarah-icon { width: 48px; height: 48px; }
	.kv-trust .kv-trust__head { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	/* No floating arrows from here down. The 80px gutter cannot hold a 48px
	   arrow standing 88 outside the rail, and the frames at 834 and 375 draw
	   none: the dots and the cut-off card say the row can be swiped. */
	/* The tablet reviews band, node 2:24356: 64 above and below, the dots 32
	   under the cards and the button 48 under the dots. The carousel block
	   carries no space under the dots below 1440, nodes 2:24908 and 2:23551,
	   so the 24 the desktop block has goes. */
	.kv-reviews { padding: 64px var(--kv-gutter); }
	.kv-reviews .kv-cards__dots { margin-top: 32px; margin-bottom: 0; }
	/* Two classes deep, because the rule it is overriding sits later in the
	   file and would otherwise win. */
	.kv-reviews .kv-reviews__cta { margin: 48px 0 0; }
	.kv-reviews__row .kv-arrows { display: none; }
	/* Node 2:24358: H3, and 48 under the head. */
	.kv-reviews .kv-reviews__head h2 { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	.kv-reviews__head { margin-bottom: 48px; }
	/* A card and most of the next, so the row reads as scrollable here too. */
	/* The tablet card is 400 with 16 between, node 2:24362, and prints a
	   step down: Subheading 1 over Subheading 2, on 20 of padding. */
	.kv-reviews__track { grid-auto-columns: 400px; gap: 16px; }
	.kv-review { padding: 20px; }
	.kv-review .kv-review__title { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-review__body { font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2); }
	.kv-sitemap__list { columns: 2; }
}

/* Phone */
@media (max-width: 767px) {
	/* The shop's masthead starts 48 under the header on a phone, node
	   2:23467, where the gutter is 16, and the browse card sits 32 under the
	   heading rather than the 48 the wider screens use. */
	.kv-main { padding-top: 48px; }
	.kv-shoppage .kv-cards__track { margin-top: 32px; }
	/* The crumbs sit 16 above the page heading here, not 24. */
	.kv-cards .kv-crumbs { margin-bottom: 16px; }
	/* And the count under the bar is Body 2, 16 under it, node 2:23532. */
	.kv-results { margin: 16px 0 32px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	/* On an archive the grid follows 24 under the count, node 2:23594; the
	   shop keeps 32, node 2:23533. */
	.kv-main:has(> .kv-termhead) .kv-results { margin-bottom: 24px; }
	.kv-cards .kv-cards__heading { font-size: 32px; line-height: 40px; }
	.kv-cards h2.kv-cards__heading { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-cards__head { align-items: center; }
	/* The phone card is 280 with 16 between, node 2:23368, so the next one
	   shows at the edge and the row reads as something to swipe. */
	.kv-cards__track { grid-auto-columns: 280px; gap: 16px; margin-top: 24px; }
	/* The heading and the sentence under it are centred on the phone, node
	   2:23368. The shop page's own heading is not, so this is the home
	   page's bands only. */
	.kv-home .kv-cards__words { align-items: center; text-align: center; }
	.kv-cards__dots { margin-top: 36px; }
	.kv-shoppage__bar { flex-direction: column; gap: 16px; margin-top: 32px; }
	.kv-filters { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; gap: 12px; scrollbar-width: none; }
	.kv-filters::-webkit-scrollbar { width: 0; height: 0; }
	.kv-filter > summary { height: 40px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-filter__panel { min-width: 240px; }
	.kv-filter__tick { width: 20px; height: 20px; }
	/* Two across at 375: cards at 0 and 179, each 164, so 15 between them,
	   and rows 270 tall 290 apart, so 20 under each one. Nodes 2:23534 on. */
	.kv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 15px; row-gap: 20px; }
	/* The small card, node 1:3734: 164 wide, the words 12 under the picture
	   and 10 apart inside, the name Body 2 clamped to two lines, the price
	   Body 2 with a 6 column gap, and the badges Caption on a rail 6 from the
	   left and 8 from the foot of the picture. The name rule has to say
	   `.kv-card` as well, because the rule it is overriding does. */
	.kv-card__link { gap: 12px; }
	.kv-card__body { gap: 10px; }
	.kv-card .kv-card__title { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-card .kv-price { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); gap: 4px 6px; }
	.kv-card .kv-tag { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
	.kv-card__tags { left: 6px; bottom: 8px; }
	/* The mark is the one thing the phone does not shrink: the commissioned
	   set stopped reading at 24, so it keeps the 32 floor and the button
	   around it sits 4 out to land the mark on the frame's 8. */
	.kv-card__wish { top: 4px; right: 4px; }
	/* Node 2:23367. The three marks stop being columns and become rows: the
	   pill moves from over the words to beside them and everything reads from
	   the left margin. The band is 36 deep, the rows 24 apart, the pill 32 of
	   glyph in 12 of padding, and 20 of it is a Subheading 1 head over a
	   Body 1 line, 8 apart. */
	.kv-trust { margin-top: 64px; padding: 36px var(--kv-gutter); }
	.kv-trust__inner { flex-direction: column; align-items: stretch; gap: 24px; }
	.kv-trust__col {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		grid-template-areas: "icon head" "icon body";
		column-gap: 20px; row-gap: 8px;
		align-items: start; text-align: left;
	}
	.kv-trust__icon { grid-area: icon; align-self: start; padding: 12px; }
	.kv-trust__icon .karivarah-icon { width: 32px; height: 32px; }
	.kv-trust .kv-trust__head { grid-area: head; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-trust__body { grid-area: body; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	/* 36 on a phone, node 2:23551 on the shop and 2:23402 on the home
	   page, which are the same band at the same size. */
	.kv-reviews { padding: 36px var(--kv-gutter); }
	/* Node 2:23404: H5, and 24 under the head. */
	.kv-reviews .kv-reviews__head h2 { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-reviews__head { margin-bottom: 24px; }
	.kv-reviews__head p { margin-top: 16px; }
	/* The phone band, node 2:23404: 24 between the cards, the dots and the
	   button, and the button at the small size. */
	.kv-reviews .kv-cards__dots { margin-top: 24px; margin-bottom: 0; }
	.kv-reviews .kv-reviews__cta { margin: 24px 0 0; }
	/* The phone card is 300 with 16 between, node 1:4039: 20 of padding, the
	   stars at 20, and Subheading 2 over Body 2 with 12 between the blocks. */
	.kv-reviews__track { grid-auto-columns: 300px; gap: 16px; }
	.kv-review { padding: 20px; }
	.kv-review__said { gap: 12px; }
	.kv-review .kv-star .karivarah-icon { width: 20px; height: 20px; }
	.kv-review .kv-review__title { font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2); }
	.kv-review__body { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-reviews__row .kv-arrows { display: none; }
	.kv-sitemap { padding: 64px var(--kv-gutter); gap: 36px; }
	/* Two columns on a phone as well, node 2:23567: one column turned a
	   band the frame draws at 944 into one of 1678. */
	.kv-sitemap__list { columns: 2; }
	/* The phone uses the small tile, 40 on Body 2 with a 20 mark, node
	   2:23463's pagination at 172 by 40. */
	.kv-pages { flex-wrap: wrap; }
	.kv-page,
	.nav-links .page-numbers {
		width: 40px; height: 40px;
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-page .karivarah-icon { width: 20px; height: 20px; }
}

/* The phone filter drawer, nodes 2:24214 and 2:24223 */
.kv-filterbtn { display: none; }

dialog.kv-filterbox {
	margin: 0; padding: 0; border: 0;
	width: 311px; max-width: 85vw; height: 100dvh; max-height: 100dvh;
	inset-inline-start: 0; inset-block-start: 0;
	background: var(--kv-paper); color: var(--kv-text);
}
dialog.kv-filterbox::backdrop { background: rgba(0, 0, 0, 0.4); }
.kv-filterbox__inner {
	display: flex; flex-direction: column; gap: 24px;
	height: 100%; padding: 20px 16px; overflow-y: auto;
	scrollbar-width: none;
}
.kv-filterbox__inner::-webkit-scrollbar { width: 0; height: 0; }
.kv-filterbox__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.kv-filterbox .kv-filterbox__head h2 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
.kv-filterbox .kv-filterbox__close,
.kv-filterbox .kv-filterbox__close:hover,
.kv-filterbox .kv-filterbox__close:focus {
	width: 40px; height: 40px; flex: 0 0 40px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 0 !important;
	background: none !important; box-shadow: none !important; color: var(--kv-text) !important; cursor: pointer;
}
.kv-filterbox .kv-pills { margin: 0; gap: 8px; }

.kv-fgroup > summary {
	display: flex; align-items: center; gap: 8px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); cursor: pointer; list-style: none;
}
.kv-fgroup > summary::-webkit-details-marker { display: none; }
.kv-fgroup[open] > summary { color: var(--kv-primary); text-decoration: underline; }
.kv-fgroup[open] > summary .karivarah-icon { transform: rotate(180deg); }
.kv-fgroup__opts { display: flex; flex-direction: column; gap: 16px; padding: 16px 0 0; }
.kv-fopt {
	display: flex; align-items: flex-start; gap: 12px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text) !important; text-decoration: none;
}
.kv-fbox {
	flex: 0 0 24px; width: 24px; height: 24px; margin-top: 1px;
	border: 1px solid var(--kv-text); border-radius: 4px;
}
.kv-fopt.is-on .kv-fbox {
	background: var(--kv-primary) center / 14px no-repeat
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23fff'%3E%3Cpath d='M232.49 80.49l-128 128a12 12 0 0 1-17 0l-56-56a12 12 0 1 1 17-17L96 183 215.51 63.51a12 12 0 0 1 17 17Z'/%3E%3C/svg%3E");
	border-color: var(--kv-primary);
}

@media (max-width: 767px) {
	.kv-filters { display: none; }
	.kv-shoppage__bar { flex-direction: row; align-items: center; }
	.kv-filterbtn {
		display: inline-flex; align-items: center; gap: 8px;
		height: 32px; padding: 0 12px;
		border: 1px solid var(--kv-grey-900); border-radius: 100px;
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text) !important; text-decoration: none;
	}
	.kv-filterbtn__count {
		display: inline-flex; align-items: center; justify-content: center;
		min-width: 20px; height: 20px; padding: 0 6px; border-radius: 100px;
		background: var(--kv-primary); color: var(--kv-paper); font-size: 12px; line-height: 20px;
	}
	.kv-sort .kv-filter > summary { height: 32px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-page,
	.nav-links .page-numbers { width: 40px; height: 40px; }
	/* The phone card keeps the frame's 16 between the words and the link,
	   node 1:4566, on a 20 pad and a 156 floor. */
	.kv-tcard { min-height: 156px; padding: 20px; gap: 16px; }
	.kv-tcard__name { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-tcard__desc { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-tcard__pic { width: 118px; height: 104px; }
	.kv-tcard__text { width: calc(100% - 100px); }
}

@media (min-width: 768px) {
	dialog.kv-filterbox[open] { display: none; }
}

/* A filter value with nothing behind it is shown, not offered */
.kv-filter__opt.is-empty,
.kv-fopt.is-empty { color: var(--kv-text-disabled) !important; pointer-events: none; }
.kv-fopt.is-empty .kv-fbox { border-color: var(--kv-text-disabled); }

/* A card photograph fills its corner; an illustration sits in it */
.kv-tcard__pic--photo { overflow: hidden; border-radius: 8px; }
.kv-tcard__pic--photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------------------------------------------------------------------------
   Category, craft and collection pages, node 2:23248
   ------------------------------------------------------------------------ */

/* The illustration hangs 8px below the header and is pinned to the gutter, so
   it is out of the flow: the heading column sits beside it and the collection
   links run under both, as node 2:23341 draws it. */
.kv-termhead { display: flex; flex-direction: column; align-items: stretch; gap: 36px; }
.kv-termhead__row { position: relative; display: flex; align-items: flex-start; gap: 48px; }
.kv-termhead__row:has(.kv-termhead__pic) { padding-right: 461px; }
.kv-termhead__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 24px; }
.kv-termhead .kv-crumbs { margin: 0; }
.kv-termhead .kv-termhead__title {
	margin: 0;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1);
	color: var(--kv-text);
}
.kv-termhead__desc { max-width: 596px; }
.kv-termhead__desc p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-termhead__desc p + p { margin-top: 12px; }

/* A category links down to its collections; a collection links nowhere. */
.kv-termhead__links { display: flex; flex-wrap: wrap; gap: 16px; }
/* The links run as wide as the drawing allows and wrap there, so the three the
   frame draws sit in one row, node 2:23262, and a longer list never runs under
   the drawing. */
.kv-termhead:has(.kv-termhead__pic) .kv-termhead__links { max-width: calc(100% - 413px); }
.kv-termhead__links a {
	display: inline-flex; align-items: center; justify-content: center;
	min-width: 222px; min-height: 60px; padding: 16px 24px;
	border-radius: 8px; background: var(--kv-primary-8);
	font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); text-align: center;
	color: var(--kv-text) !important; text-decoration: none;
}
.kv-termhead__links a:hover { background: var(--kv-primary-14); color: var(--kv-primary) !important; }

.kv-termhead__pic { position: absolute; top: -92px; right: 0; width: 413px; height: 413px; display: block; }
/* The drawing is out of the flow, so nothing under the header knows how tall
   it is. Where the heading column is short, which is every craft page because
   a craft has no collections to link down to, and a category with no children
   or a single row of them, the filter bar rode up into the drawing: 73px of
   overlap on the English basketry page at 1440. The header reserves the
   drawing's height instead, so the bar's own 64px margin always starts below
   it. Each number is the drawing's height less the distance it is pulled up,
   so it tracks the two rules above rather than being a guess. `min-height`
   only grows a header that is too short, so a category with enough collection
   links under it is untouched. */
.kv-termhead:has(.kv-termhead__pic) { min-height: 321px; }   /* 413 - 92 */
.kv-termhead__pic img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Accordions, node 2:23310 */
.kv-acc { padding: 100px var(--kv-gutter); }
.kv-acc__inner { max-width: 768px; margin: 0 auto; display: flex; flex-direction: column; gap: 48px; }
.kv-acc__item { border: 0; }
.kv-acc__item > summary {
	display: flex; align-items: center; gap: 24px;
	cursor: pointer; list-style: none;
}
.kv-acc__item > summary::-webkit-details-marker { display: none; }
.kv-acc .kv-acc__head {
	flex: 1 1 auto; min-width: 0;
	font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text);
}
.kv-acc__caret { width: 40px; height: 40px; flex: 0 0 40px; color: var(--kv-text); transition: transform 0.2s; }
.kv-acc__item > summary:hover .kv-acc__head { color: var(--kv-primary); }
.kv-acc__body { margin-top: 24px; }
.kv-acc__body p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-acc__body p + p { margin-top: 16px; }

/* Between the frames the 413 drawing leaves too little for the heading, so the
   834 arrangement carries up to 1180: the smaller drawing, and the collection
   links running the full width under it rather than stacking one to a row. */
@media (max-width: 1179px) {
	.kv-termhead { gap: 32px; }
	.kv-termhead__row:has(.kv-termhead__pic) { padding-right: 327px; }
	.kv-termhead__row .kv-crumbs { margin-bottom: -8px; }
	.kv-termhead:has(.kv-termhead__pic) .kv-termhead__links { max-width: none; }
	/* Three across the 674, node 2:24938: the links hold 214 rather than 222. */
	.kv-termhead__links a { min-width: 214px; }
	.kv-termhead__pic { width: 279px; height: 279px; }
	.kv-termhead:has(.kv-termhead__pic) { min-height: 187px; }   /* 279 - 92 */
}

@media (max-width: 1024px) {
	/* Node 2:24928: the crumbs tuck closer to the heading, the heading column
	   narrows to 398 and the links take the full width under the drawing. */
	.kv-termhead .kv-termhead__title { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
	.kv-termhead__row:has(.kv-termhead__pic) { padding-right: 0; }
	.kv-termhead__row:has(.kv-termhead__pic) .kv-termhead__text { max-width: 398px; min-height: 192px; }
	.kv-termhead__pic { top: -56px; }
	.kv-termhead:has(.kv-termhead__pic) { min-height: 223px; }   /* 279 - 56 */
	.kv-acc { padding: 64px var(--kv-gutter); }
	.kv-acc__inner { gap: 36px; }
	.kv-acc .kv-acc__head { font-size: 28px; line-height: 40px; }
	.kv-acc__caret { width: 32px; height: 32px; flex-basis: 32px; }
}

/* Phone, node 2:23572: the illustration sits above the crumbs, the collection
   links shrink to their text, and the accordions step down a size. */
@media (max-width: 767px) {
	/* Node 2:23577: the trail steps down with the page. */
	.kv-crumbs { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-crumbs__sep { width: 20px; height: 20px; flex-basis: 20px; }

	.kv-termhead { gap: 32px; }
	.kv-termhead__row { flex-direction: column-reverse; align-items: stretch; gap: 32px; }
	.kv-termhead .kv-termhead__title { font-size: 32px; line-height: 40px; }
	.kv-termhead__text { gap: 16px; }
	.kv-termhead__row:has(.kv-termhead__pic) .kv-termhead__text { max-width: none; min-height: 0; }
	.kv-termhead__row .kv-crumbs { margin-bottom: 0; }
	/* Node 2:23575: the drawing sits above the trail, flush under the header. */
	.kv-main:has(.kv-termhead__pic) { padding-top: 0; }
	.kv-termhead__pic { position: static; width: 240px; height: 225px; margin: 0 auto; }
	/* Back in the flow on a phone, so it measures itself. */
	.kv-termhead:has(.kv-termhead__pic) { min-height: 0; }
	.kv-termhead__links { gap: 12px; }
	.kv-termhead__links a {
		min-width: 0; min-height: 44px; padding: 8px 16px;
		font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	}
	.kv-acc { padding: 36px var(--kv-gutter); }
	.kv-acc__inner { gap: 24px; }
	.kv-acc__item > summary { gap: 16px; }
	.kv-acc .kv-acc__head { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-acc__caret { width: 24px; height: 24px; flex-basis: 24px; }
	.kv-acc__body { margin-top: 16px; }
}

/* ---------------------------------------------------------------------------
   The soft grey lines behind the tinted surfaces.

   One drawing, exported from the frames, laid over the tint rather than
   replacing it. It sits on a pseudo-element so it never covers the content, and
   it is decorative, so it is hidden from assistive technology by being CSS.
   ------------------------------------------------------------------------ */

.kv-tcard,
.kv-review,
.kv-trust,
.kv-sitemap,
.kv-band--tinted,
.kv-termhead__links a { position: relative; isolation: isolate; }

/* The sections carry the drawing at its own scale; the cards show a corner of
   it, which is how the frames use it. */
.kv-trust::before { background-size: 115% auto; background-position: center; }
.kv-sitemap::before,
.kv-band--tinted::before { background-size: 110% auto; transform: rotate(180deg); }

/* A band that changes colour while the reviews are switched off (inc/home.php,
   woocommerce/archive-product.php). The wrapper runs edge to edge, so the
   tint does too, the way the sitemap's does; the band inside keeps its column. */
.kv-band--tinted { background: var(--kv-primary-4); }
.kv-band--plain > .kv-hfaq,
.kv-band--plain > .kv-sitemap { background: none; }
.kv-band--plain > .kv-sitemap::before,
.kv-band--plain > .kv-hfaq > .kv-veins { display: none; }
.kv-tcard::before { background-size: 180% auto; background-position: 30% 40%; }
.kv-review::before { background-size: 140% auto; background-position: 60% 35%; }

/* ---------------------------------------------------------------------------
   Product page, node 2:25558
   ------------------------------------------------------------------------ */

/* The trail wraps inside the picture column rather than running on past it.
   The frame runs it the full 1136 on one line, node 2:25564; the cap is the
   client's and stays. */
.kv-pdp .kv-crumbs { margin-bottom: 48px; max-width: 45.8%; }
/* 45.8% of the 1136 content column is the frame's 520, and it keeps that
   proportion down to the tablet layout instead of crushing the summary. */
.kv-pdp__grid { display: grid; grid-template-columns: minmax(0, 45.8%) minmax(0, 1fr); gap: 48px; align-items: start; }

.kv-pdp__frame {
	position: relative;
	width: 100%; aspect-ratio: 1 / 1;
	border-radius: 12px; overflow: hidden; background: var(--kv-grey-400);
}
.kv-pdp__strip {
	display: grid; grid-auto-flow: column; grid-auto-columns: 100%;
	width: 100%; height: 100%;
	overflow-x: auto; overflow-y: hidden;
	scroll-snap-type: x mandatory; scrollbar-width: none;
	overscroll-behavior-x: contain;
}
.kv-pdp__strip::-webkit-scrollbar { width: 0; height: 0; }
.kv-pdp__slide { scroll-snap-align: start; width: 100%; height: 100%; }
.kv-pdp__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Node 2:25576: six 100 squares, 16 apart, left aligned under the picture
   rather than stretched to fill the column. */
.kv-pdp__thumbs {
	list-style: none; margin: 16px 0 0; padding: 0;
	display: flex; flex-wrap: wrap; gap: 16px;
}
.kv-pdp__thumbs > li { flex: 0 0 100px; width: 100px; }
.kv-pdp .kv-pdp__thumb,
.kv-pdp .kv-pdp__thumb:hover,
.kv-pdp .kv-pdp__thumb:focus {
	display: block; width: 100%; aspect-ratio: 1 / 1; overflow: hidden;
	padding: 0 !important; border: 1px solid transparent !important; border-radius: 8px !important;
	background: var(--kv-grey-400) !important; box-shadow: none !important; cursor: pointer;
}
.kv-pdp__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kv-pdp .kv-pdp__thumb.is-on { border-color: var(--kv-text) !important; }

.kv-pdp__summary { display: flex; flex-direction: column; gap: 24px; }
.kv-pdp__origin { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-pdp .kv-pdp__title {
	/* The origin line sits 12 above the name where the column gives 24. */
	margin: -12px 0 0; font-weight: var(--kv-weight);
	font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); color: var(--kv-text);
	text-wrap: pretty;
}
.kv-pdp__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px; margin-top: -4px; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
.kv-pdp__now { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-pdp__price.is-sale .kv-pdp__now { color: var(--kv-primary); }
.kv-pdp__vat { color: var(--kv-text-2); }
.kv-pdp__was { color: var(--kv-text-2); text-decoration: line-through; }
.kv-pdp__save { font-weight: var(--kv-weight-semibold); color: var(--kv-primary); }
.kv-pdp__price .woocommerce-Price-amount { font: inherit; color: inherit; }

/* Node 2:25607 draws "Color: Beige" with the attribute in the secondary grey
   and the value chosen in the text colour, and this line had them the other
   way round. The same pairing serves the label over the circles below, which
   is the same sentence on a variable product. */
.kv-pdp__colour p { margin: 0 0 8px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-pdp__colour p span { color: var(--kv-text-2); }
.kv-swatches { display: flex; flex-wrap: wrap; gap: 12px; }
.kv-swatch {
	width: 56px; height: 56px; border-radius: 100px;
	border: 1px solid var(--kv-grey-900); display: block;
}

/* Buy row: Woo's own form, dressed to the frame */
.kv-pdp__buy { display: block; }
.kv-pdp__buy form.cart { flex: 1 1 auto; min-width: 0; display: flex; align-items: flex-end; gap: 16px; margin: 0; }
.kv-pdp__buy .quantity { display: flex; align-items: center; }
.kv-pdp__buy .quantity .qty {
	width: 114px; height: 56px; padding: 0 12px;
	border: 1px solid var(--kv-grey-900); border-radius: 8px; background: var(--kv-paper);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); text-align: center;
}
.kv-pdp .kv-pdp__buy button[type="submit"],
.kv-pdp .kv-pdp__buy button[type="submit"]:hover {
	flex: 1 1 auto; min-height: 56px; padding: 16px 24px !important;
	border: 0 !important; border-radius: 16px !important;
	background: var(--kv-primary) !important; color: var(--kv-white) !important;
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); font-weight: var(--kv-weight); cursor: pointer;
	min-width: 0; white-space: normal; overflow-wrap: anywhere;
}
.kv-pdp .kv-pdp__buy button[type="submit"]:focus-visible { background: var(--kv-primary) !important; box-shadow: var(--kv-elevation-primary) !important; }
@media (hover: hover) {
	.kv-pdp .kv-pdp__buy button[type="submit"]:hover { background: var(--kv-primary) !important; box-shadow: var(--kv-elevation-primary) !important; }
}
.kv-pdp .kv-pdp__buy button[type="submit"]:active { background: var(--kv-primary-dark) !important; box-shadow: var(--kv-elevation-primary) !important; }
.kv-pdp .kv-pdp__wish,
.kv-pdp .kv-pdp__wish:hover,
.kv-pdp .kv-pdp__wish:focus {
	/* Square, and as tall as the row rather than a fixed 56: the button
	   beside it is one line on a desktop and can be two on a phone, and a
	   heart that stayed 56 stood taller or shorter than whatever it was
	   paired with. */
	flex: 0 0 56px; width: 56px; min-height: 56px; height: auto; align-self: stretch;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 1px solid var(--kv-grey-900) !important; border-radius: 16px !important;
	background: none !important; box-shadow: none !important; color: var(--kv-text) !important; cursor: pointer;
}
.kv-pdp .kv-pdp__wish:hover { color: var(--kv-primary) !important; border-color: var(--kv-primary) !important; }
.kv-pdp__wish .karivarah-icon { width: 24px; height: 24px; }

.kv-pdp__reassure { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 20px 0; }
.kv-pdp__reassure .kv-marks { justify-content: center; }
.kv-pdp__returns { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-pdp__returns a { color: var(--kv-primary) !important; }

/* The four sections, node 2:25691 */
.kv-pacc { display: flex; flex-direction: column; }
.kv-pacc__item { border-bottom: 1px solid var(--kv-grey-400); }
.kv-pacc__item > summary {
	display: flex; align-items: center; gap: 8px;
	/* The hairline comes out of the padding so the row holds the frame's 64,
	   node 2:25693. The 20 the frame puts above and below its 24 icon becomes
	   16 here, because the commissioned mark carries a 32 floor. */
	padding: 16px 20px 15px; cursor: pointer; list-style: none;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-pacc__item > summary::-webkit-details-marker { display: none; }
.kv-pacc .kv-pacc__icon { width: 24px; height: 24px; flex: 0 0 24px; }
.kv-pacc__head { flex: 1 1 auto; min-width: 0; }
.kv-pacc__caret { width: 24px; height: 24px; flex: 0 0 24px; color: var(--kv-text); transition: transform 0.2s; }
.kv-pacc__item > summary:hover { color: var(--kv-primary); }
.kv-pacc__body { padding: 0 20px 20px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-pacc__body p { margin: 0 0 12px; }
.kv-pacc__body p:last-child { margin-bottom: 0; }

/* Share */
.kv-share { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.kv-share__label { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-share__links { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.kv-share .kv-share__link,
.kv-share .kv-share__link:hover,
.kv-share .kv-share__link:focus {
	position: relative;
	width: 32px; height: 32px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important;
	color: var(--kv-text) !important; cursor: pointer; text-decoration: none;
}
.kv-share .kv-share__link:hover { color: var(--kv-primary) !important; }
.kv-share__copied {
	position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
	padding: 2px 8px; border-radius: 4px; background: var(--kv-text); color: var(--kv-page);
	font-size: 12px; line-height: 20px; white-space: nowrap;
}

/* Product rows, same carousel behaviour as the browse cards */
/* The frame ends the summary where the next band begins, node 2:25563, because
   the band below it is white. Here the client's first row is the tinted one,
   so the page keeps a band's distance below the share row rather than running
   the tint straight into it. The scale is the band scale, so the boundary
   falls where it does between any two bands on the home page. */
.kv-pdp { padding-bottom: 100px; }

.kv-prow { max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter); position: relative; }
.kv-prow--veins { isolation: isolate; }
.kv-prow--veins { padding-bottom: 100px; }
/* Tinted, so edge to edge like every tinted band; the side padding grows on a
   wide screen so the row itself stays in the 1136 column (152 at 1440). */
.kv-prow--veins { max-width: none; padding-inline: max(var(--kv-gutter), calc((100% - 1136px) / 2)); }
.kv-prow__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 64px; }
.kv-prow .kv-prow__head h2 {
	margin: 0; font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text);
}
.kv-prow__rail { position: relative; }
/* The arrows stand in the gutter, clear of the cards, centred on the rail:
   node I2:22409;18302:45519 puts them 64 outside the 1136 on either side, and
   48 wide means the box starts 88 out. Below 1025 the gutter is 80 and cannot
   hold them, which is why the frames at 834 and 375 draw none. */
.kv-prow__rail > .kv-arrows {
	position: absolute; inset: 0; z-index: 2;
	justify-content: space-between; align-items: center;
	pointer-events: none;
}
.kv-prow__rail > .kv-arrows .kv-arrow {
	position: relative; pointer-events: auto;
	width: 48px !important; height: 48px !important; flex-basis: 48px;
	background: var(--kv-grey-300) !important;
}
.kv-prow__rail > .kv-arrows [data-kv-prev] { margin-left: -88px; }
.kv-prow__rail > .kv-arrows [data-kv-next] { margin-right: -88px; }

/* The rail is cut at the content column, not at the glass. Nodes 2:22409 on
   the home page and I2:25721;18302:47805 on the product page are both 1136
   wide and both clip, so four 266 cards fill the rail exactly and the fifth is
   not there. That is what leaves the gutter either side free for an arrow to
   stand in. Below 1025 there are no arrows and the rail bleeds instead. */
.kv-prow__track {
	display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 72px) / 4);
	gap: 24px;
	overflow-x: auto; overflow-y: hidden;
	scroll-snap-type: x mandatory; scrollbar-width: none;
}
.kv-prow__track::-webkit-scrollbar { width: 0; height: 0; }
.kv-prow__track > .kv-card { scroll-snap-align: start; }
/* No frame draws dots under a product rail, nodes 2:22409, 2:22449, 2:25721
   and 2:25725: above 1025 the arrows say the row moves, and below it the cut
   card says the same thing. */
.kv-prow > .kv-cards__dots { display: none; }

@media (max-width: 1024px) {
	/* Node 2:25017: a 280 picture column, 32 apart from a 362 summary. */
	.kv-pdp__grid { grid-template-columns: 280px minmax(0, 1fr); gap: 32px; }
	.kv-pdp .kv-crumbs { max-width: 280px; }
	.kv-pdp .kv-pdp__title { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	/* Node 2:25025: 80 squares, 12 apart. */
	.kv-pdp__thumbs { gap: 12px; }
	.kv-pdp__thumbs > li { flex-basis: 80px; width: 80px; }
	.kv-pdp__box .kv-marks { gap: 10px; }
	.kv-pdp { padding-bottom: 64px; }
	.kv-prow { padding: 64px var(--kv-gutter); }
	.kv-prow__head { margin-bottom: 48px; }
	.kv-prow .kv-prow__head h2 { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	/* With the arrows gone the rail runs off the screen again, node 2:24256,
	   and the cut card carries the whole of the message. */
	.kv-prow__track {
		grid-auto-columns: 214px; gap: 20px;
		margin-right: calc(-1 * var(--kv-gutter));
		padding-right: var(--kv-gutter);
	}
}

@media (max-width: 767px) {
	/* Node 2:23646: the page starts 36 under the header. The frame's trail is
	   two levels and holds one line; this one carries the whole path, so a
	   deep product takes two. */
	.kv-pdp { padding-top: 36px; }
	.kv-pdp .kv-crumbs { margin-bottom: 16px; max-width: none; }
	.kv-pdp__grid { grid-template-columns: minmax(0, 1fr); gap: 24px; }
	.kv-pdp__thumbs {
		display: flex; gap: 8px;
		margin-right: calc(-1 * var(--kv-gutter));
		padding-right: var(--kv-gutter);
		overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
	}
	.kv-pdp__thumbs::-webkit-scrollbar { width: 0; height: 0; }
	/* Node 2:23661: 60 squares, 8 apart, and the row runs off the edge. */
	.kv-pdp__thumbs > li { flex: 0 0 60px; width: 60px; }
	/* Node 2:23681: the name steps to H6 and the price to Subtitle 1. */
	.kv-pdp .kv-pdp__title { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-pdp__origin { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp__price .kv-pdp__now { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	/* Node 2:23787: a 52 row on 16, with 20 icons. */
	.kv-pacc__item > summary { padding: 10px 16px 9px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pacc .kv-pacc__icon,
	.kv-pacc__caret { width: 20px; height: 20px; flex-basis: 20px; }
	.kv-pacc__body { padding: 0 16px 16px; }
	.kv-pdp__note { padding: 16px; }
	.kv-share__label { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp__buy { flex-wrap: wrap; }
	.kv-pdp__buy form.cart { gap: 12px; }
	/* The circles hold 56 on a phone too, node 2:23696. */
	.kv-pdp { padding-bottom: 36px; }
	.kv-prow { padding: 36px var(--kv-gutter); }
	.kv-prow .kv-prow__head h2 { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-prow__head { margin-bottom: 24px; }
	/* Two cards and the edge of a third, node 2:23357: 156 apiece, 9 apart. */
	.kv-prow__track { grid-auto-columns: 156px; gap: 9px; }
}

/* ---------------------------------------------------------------------------
   Tables, node 2:25394. Product details, blog posts, anything later.
   ------------------------------------------------------------------------ */

.kv-table__scroll {
	overflow-x: auto;
	background: var(--kv-grey-100);
	border-radius: 12px;
}
.kv-table {
	width: 100%; border-collapse: separate; border-spacing: 0;
	background: transparent;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}
/* The kit stripes every table with tr:nth-child(2n+1) > td, which outranks a
   plain class, so this says it at the cell. */
.kv-table tbody tr > th,
.kv-table tbody tr > td,
.kv-table tbody tr:hover > th,
.kv-table tbody tr:hover > td { background-color: transparent !important; }
/* Nothing inherits a border: the dividers below are the only lines, which is
   what keeps the rounded corners of the wrapper clean. */
.kv-table,
.kv-table thead,
.kv-table tbody,
.kv-table tr,
.kv-table th,
.kv-table td { border: 0; }
.kv-table thead th { background: var(--kv-grey-400); color: var(--kv-text); font-weight: var(--kv-weight); text-align: left; }
.kv-table thead th + th { border-left: 1px solid var(--kv-paper); }
.kv-table th,
.kv-table td { padding: 12px; vertical-align: top; }
.kv-table tbody th,
.kv-table tbody td { color: var(--kv-text-2); font-weight: var(--kv-weight); text-align: left; }
.kv-table tbody tr + tr th,
.kv-table tbody tr + tr td { border-top: 1px solid var(--kv-grey-500); }
.kv-table tbody th + td,
.kv-table tbody td + td { border-left: 1px solid var(--kv-grey-500); }
/* A table whose first column is its headings, as the product details are. */
/* In a label and value table the first column is the header, so it takes the
   heading row's colours from node 2:25394. */
/* Two classes and the row, so this outranks the rule above that clears the
   kit's zebra striping off every cell. */
.kv-table.kv-table--rows tbody tr > th {
	width: 40%;
	background-color: var(--kv-grey-400) !important;
	color: var(--kv-text);
}
/* Inside the heading the dividers are white, as they are in the heading row of
   node 2:25394; the body keeps the darker hairline. */
.kv-table--rows tbody th + td,
.kv-table--rows tbody tr + tr th { border-left-color: var(--kv-paper); border-top-color: var(--kv-paper); }
.kv-table th, .kv-table td { overflow-wrap: anywhere; }

/* A table stays a table on a phone and scrolls sideways, node 2:24044. */
@media (max-width: 767px) {
	.kv-table th, .kv-table td { padding: 10px 12px; }
	.kv-table--rows tbody th { width: 40%; }
}

/* ---------------------------------------------------------------------------
   The pieces of the product page the frame has and the first pass missed
   ------------------------------------------------------------------------ */

/* Origin, with a flag per country */
.kv-pdp__country { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.kv-flag { width: 24px; height: 18px; border-radius: 2px; display: block; }

/* The big picture carries the badges and the zoom control, node 2:25569 */
.kv-pdp__frame { position: relative; }
.kv-pdp__tags {
	position: absolute; left: 16px; bottom: 16px;
	display: flex; flex-direction: column-reverse; align-items: flex-start; gap: 16px;
}
/* It is drawn even when there is nothing in it, because a variable product's
   sold-out tag arrives with the choice. Empty, it must take no room and catch
   nothing. */
.kv-pdp__tags:empty { display: none; }
.kv-pdp__tags { pointer-events: none; }
/* And when the chosen variation is gone, that is the only thing worth saying
   about it, which is the rule the card already follows. */
.kv-pdp__tags.is-sold-out [data-kv-badge] { display: none; }
.kv-tag--big { padding: 8px 12px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-pdp .kv-pdp__zoom,
.kv-pdp .kv-pdp__zoom:hover,
.kv-pdp .kv-pdp__zoom:focus {
	position: absolute; right: 16px; bottom: 16px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 12px !important; border: 1px solid var(--kv-text-2) !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important;
	color: var(--kv-text) !important; cursor: pointer;
}
.kv-pdp .kv-pdp__zoom:hover { color: var(--kv-primary) !important; border-color: var(--kv-primary) !important; }

/* The thumbnails all sit at full strength. Node 2:25576 draws six identical
   squares and marks the chosen one with a stroke, nothing more; they were
   sitting back at 55%, which is not in the frame and reads as a stock state on
   a page where a fade now means sold out. The stroke is `.is-on` above, and it
   is enough on its own. */

/* The buy block, node 2:25618: the quantity on its own row under its label,
   then the button across the width with the heart beside it. */
.kv-pdp__buy form.cart:not(.variations_form) {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 56px;
	grid-template-areas: "qlabel qlabel" "qty qty" "submit wish";
	gap: 24px 12px;
	align-items: center;
}
.kv-pdp__buy form.cart:not(.variations_form) .kv-qty__label { grid-area: qlabel; margin: 0; }
.kv-pdp__buy form.cart:not(.variations_form) .quantity { grid-area: qty; justify-self: start; }
.kv-pdp__buy form.cart:not(.variations_form) button[type="submit"] { grid-area: submit; }
.kv-pdp__buy form.cart:not(.variations_form) .kv-pdp__wish { grid-area: wish; }

.kv-pdp__buy .quantity {
	display: flex; align-items: center; gap: 12px;
	/* 40 tall with the stroke inside, as the select beside it. */
	padding: 7px 11px; border: 1px solid var(--kv-grey-600); border-radius: 8px;
	background: var(--kv-paper);
}
.kv-pdp__buy .quantity .qty {
	width: 18px; height: auto; padding: 0; border: 0; background: none;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); text-align: center;
	-moz-appearance: textfield;
}
.kv-pdp__buy .quantity .qty::-webkit-outer-spin-button,
.kv-pdp__buy .quantity .qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.kv-pdp .kv-qty__step,
.kv-pdp .kv-qty__step:hover,
.kv-pdp .kv-qty__step:focus {
	width: 24px; height: 24px; flex: 0 0 24px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 4px !important;
	background: none !important; box-shadow: none !important; color: var(--kv-text) !important; cursor: pointer;
}
.kv-pdp .kv-qty__step:hover { color: var(--kv-primary) !important; }
.kv-qty__step .karivarah-icon { width: 20px; height: 20px; }
.kv-qty__label { display: block; margin-bottom: 8px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-pdp__buy form.cart { align-items: flex-end; }
.kv-pdp__buy .quantity { align-self: flex-end; }

/* Variations: Woo's own form, laid out like node 2:25619 */
/* 24 between the attributes, the controls and the buttons, node 2:25618. */
.kv-pdp form.variations_form { display: flex; flex-direction: column; align-items: stretch; gap: 24px; margin: 0; }
.kv-pdp .single_variation_wrap { width: 100%; }
.kv-pdp table.variations th { text-align: left; }
.kv-pdp table.variations,
.kv-pdp table.variations tbody { display: block; width: 100%; border: 0; margin: 0; }
.kv-pdp table.variations tbody { display: flex; flex-wrap: wrap; gap: 16px; }
.kv-pdp table.variations tr { display: flex; flex-direction: column; gap: 8px; width: 160px; }
/* A row of circles wants the width; a dropdown does not. */
.kv-pdp table.variations tr.kv-has-swatches { width: 100%; }
.kv-pdp table.variations th,
.kv-pdp table.variations td { display: block; padding: 0; border: 0; background: none; }
.kv-pdp table.variations label { display: block; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); font-weight: var(--kv-weight); }
/* What has been chosen, written after the attribute's own name. */
.kv-pdp .kv-vchosen { color: var(--kv-text); }
/* The size field is moved out of .variations into the controls row, so both
   places have to be named. */
.kv-pdp .variations select,
.kv-pdp .kv-controls select {
	/* The stroke comes out of the padding, node 1:3016: the frame draws the
	   control 40 tall on 8 and 12, and a border added on top made it 42. */
	width: 100%; padding: 7px 31px 7px 11px;
	border: 1px solid var(--kv-grey-600) !important; border-radius: 8px !important;
	background-color: var(--kv-paper);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
	/* The system select has its own border and rounding; this is ours. */
	-webkit-appearance: none; appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23231F20'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 10px center;
	background-size: 16px 16px;
}
.kv-pdp .variations select:focus,
.kv-pdp .kv-controls select:focus { border-color: var(--kv-primary) !important; outline: none; }
.kv-pdp .reset_variations { display: inline-block; margin-top: 4px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2) !important; }

/* The variation's price is written into the one under the product name, so
   Woo's second copy under the swatches is not wanted. */
.kv-pdp .woocommerce-variation-price { display: none; }
.kv-pdp__price .price { font: inherit; color: inherit; }
.kv-pdp__price del { color: var(--kv-text-2); }
.kv-pdp__price ins { text-decoration: none; color: var(--kv-primary); }
.kv-pdp .woocommerce-variation-add-to-cart {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 56px;
	grid-template-areas: "qlabel qlabel" "qty qty" "submit wish";
	gap: 24px 12px;
	align-items: center;
}
.kv-pdp .woocommerce-variation-add-to-cart .kv-qty__label { grid-area: qlabel; margin: 0; }
.kv-pdp .woocommerce-variation-add-to-cart .quantity { grid-area: qty; justify-self: start; }
.kv-pdp .woocommerce-variation-add-to-cart button[type="submit"] { grid-area: submit; }
.kv-pdp .woocommerce-variation-add-to-cart .kv-pdp__wish { grid-area: wish; }

/* The two tinted boxes and the handmade note, nodes 2:25629 and 2:25695 */
.kv-pdp__reassure { display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding: 0; }
.kv-pdp__box {
	display: flex; align-items: center; justify-content: center;
	margin: 0; padding: 20px; border-radius: 16px;
	background: var(--kv-primary-8);
	text-align: center;
}
.kv-pdp__box .kv-marks { justify-content: center; flex-wrap: nowrap; }
.kv-pdp__returns { display: block; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-pdp__returns a { color: var(--kv-text) !important; text-decoration: none; }
.kv-pdp__returns a:hover { color: var(--kv-primary) !important; }
.kv-pdp__note {
	margin: 0; padding: 20px; border-radius: 8px;
	background: var(--kv-primary-8);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}

/* The share icons sit in their own tinted circles, node 2:25699 */
.kv-share .kv-share__link,
.kv-share .kv-share__link:hover,
.kv-share .kv-share__link:focus {
	background: var(--kv-primary-8) !important;
	color: var(--kv-primary) !important;
}
.kv-share .kv-share__link:hover { background: var(--kv-primary-16) !important; }

/* The heart beside the button, node 2:25628 */
.kv-pdp .kv-pdp__wish,
.kv-pdp .kv-pdp__wish:hover,
.kv-pdp .kv-pdp__wish:focus { border: 1.5px solid var(--kv-text) !important; }
.kv-pdp__wish .karivarah-icon { width: 32px; height: 32px; }

/* The heart's frame and the button beside it are the same height, whatever
   either of them would be on its own. Both grids centre their items, so each
   was as tall as its own contents and the two matched only while both came
   out at 56. */
.kv-pdp__buy form.cart:not(.variations_form) button[type="submit"],
.kv-pdp__buy form.cart:not(.variations_form) .kv-pdp__wish,
.kv-pdp .woocommerce-variation-add-to-cart button[type="submit"],
.kv-pdp .woocommerce-variation-add-to-cart .kv-pdp__wish,
.kv-pdp__buy--wait .kv-wait__open,
.kv-pdp__buy--wait .kv-pdp__wish { align-self: stretch; height: auto; }

@media (max-width: 767px) {
	/* 12px off the corner on a 343 picture reads like the 16px the frame has
	   on a 520 one; 8 sat too close to the rounding. */
	.kv-pdp__tags { left: 12px; bottom: 12px; gap: 8px; }
	.kv-tag--big { padding: 6px 8px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp .kv-pdp__zoom { right: 12px; bottom: 12px; padding: 8px !important; }
	.kv-table th, .kv-table td { padding: 10px; }
}

/* ---------------------------------------------------------------------------
   The full size gallery, node 2:26626
   ------------------------------------------------------------------------ */

/* The shell, `.kv-lightbox`, carries the geometry. What is left here is the
   overlay, which the two frames disagree on: the magnifier is drawn over the
   near black and the gallery over black at 40%. */
dialog.kv-zoom { background: var(--kv-text); display: none; }
/* A grid centres the panel whatever hangs off it; hidden overflow keeps an
   absolutely positioned control from widening the dialog and sliding it. */
dialog.kv-zoom[open] { display: grid; place-items: center; overflow: hidden; }
dialog.kv-zoom { --kv-lightbox-backdrop: var(--kv-text); }

.kv-zoom__panel { width: min(600px, 86vw); }

.kv-zoom .kv-zoom__close,
.kv-zoom .kv-zoom__close:hover,
.kv-zoom .kv-zoom__close:focus {
	position: absolute; top: 0; left: calc(100% + 112px); z-index: 3;
	width: 40px; height: 40px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important;
	color: var(--kv-page) !important; cursor: pointer;
}
.kv-zoom__close .karivarah-icon { width: 24px; height: 24px; }

.kv-zoom__stage { position: relative; }
.kv-zoom__strip {
	display: grid; grid-auto-flow: column; grid-auto-columns: 100%;
	width: 100%; aspect-ratio: 1 / 1;
	overflow-x: auto; overflow-y: hidden;
	scroll-snap-type: x mandatory; scrollbar-width: none;
	border-radius: 8px; background: var(--kv-grey-400);
}
.kv-zoom__strip::-webkit-scrollbar { width: 0; height: 0; }
.kv-zoom__slide { scroll-snap-align: start; width: 100%; height: 100%; }
.kv-zoom__img { width: 100%; height: 100%; object-fit: contain; display: block; }

.kv-zoom .kv-zoom__nav,
.kv-zoom .kv-zoom__nav:hover,
.kv-zoom .kv-zoom__nav:focus {
	position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
	width: 48px; height: 48px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px !important;
	background: var(--kv-grey-100) !important; box-shadow: none !important;
	color: var(--kv-text) !important; cursor: pointer;
}
.kv-zoom .kv-zoom__nav:hover { color: var(--kv-primary) !important; }
.kv-zoom__nav .karivarah-icon { width: 24px; height: 24px; }

.kv-zoom__thumbs {
	list-style: none; margin: 16px 0 0; padding: 0;
	display: flex; gap: 16px;
	overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
}
.kv-zoom__thumbs::-webkit-scrollbar { width: 0; height: 0; }
.kv-zoom .kv-zoom__thumb,
.kv-zoom .kv-zoom__thumb:hover,
.kv-zoom .kv-zoom__thumb:focus {
	display: block; width: 100px; height: 100px; flex: 0 0 100px; overflow: hidden;
	padding: 0 !important; border: 1px solid transparent !important; border-radius: 8px !important;
	background: var(--kv-grey-400) !important; box-shadow: none !important; cursor: pointer;
}
.kv-zoom__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0.75; }
.kv-zoom .kv-zoom__thumb.is-on { border-color: var(--kv-primary) !important; }
.kv-zoom .kv-zoom__thumb.is-on img,
.kv-zoom .kv-zoom__thumb:hover img { opacity: 1; }

@media (max-width: 1024px) {
	.kv-zoom__panel { width: min(600px, 74vw); }
	/* No room beside the panel here, so the close sits on the picture. */
	.kv-zoom .kv-zoom__close,
	.kv-zoom .kv-zoom__close:hover,
	.kv-zoom .kv-zoom__close:focus {
		left: auto; right: 8px; top: 8px;
		background: var(--kv-paper) !important; color: var(--kv-text) !important;
	}
	.kv-zoom__nav[data-kv-zoom-prev] { right: auto; left: 8px; }
	.kv-zoom__nav[data-kv-zoom-next] { left: auto; right: 8px; }
	.kv-zoom .kv-zoom__thumb { width: 72px; height: 72px; flex-basis: 72px; }
}

@media (max-width: 767px) {
	.kv-zoom__panel { width: calc(100vw - 32px); }

	/* The thumbnails do the stepping, so the arrows go.

	   The close comes back, 14.10.2026, reversing the 09.10.2026 request that
	   hid it: above the picture on the overlay, where it is not on the
	   photograph and is the only thing at the top of the screen. The gallery's
	   view does the same. */
	.kv-zoom .kv-zoom__nav { display: none; }
	.kv-zoom .kv-zoom__close,
	.kv-zoom .kv-zoom__close:hover,
	.kv-zoom .kv-zoom__close:focus {
		/* The icon is 24 in a 40 press, so 8 inside it: 8 lands it on the
		   same 16 gutter the picture keeps. */
		position: fixed; top: 12px; right: 8px; left: auto; bottom: auto;
		transform: none;
		width: 40px; height: 40px; margin: 0; overflow: visible;
		clip-path: none;
		background: none !important; color: var(--kv-page) !important;
	}
	.kv-zoom__thumbs { gap: 8px; margin-top: 12px; }
	.kv-zoom .kv-zoom__thumb { width: 56px; height: 56px; flex-basis: 56px; }

	/* The badge row and the returns line hold one line at every width. */
	.kv-pdp__box { padding: 12px; }
	.kv-pdp__box .kv-marks { gap: 8px; }
	.kv-pdp__box .kv-marks svg { height: 20px; }
}

/* A disabled stepper says so quietly */
.kv-pdp .kv-qty__step[disabled] { color: var(--kv-text-disabled) !important; cursor: default; }

/* Colour and style variations as circles, node 2:25610 */
.kv-vswatches { display: flex; flex-wrap: wrap; gap: 12px; }
.kv-pdp .kv-vswatch,
.kv-pdp .kv-vswatch:hover,
.kv-pdp .kv-vswatch:focus {
	width: 64px; height: 64px; flex: 0 0 64px;
	display: inline-flex; align-items: center; justify-content: center;
	padding: 3px !important; border: 1px solid transparent !important; border-radius: 100px !important;
	background: none !important; box-shadow: none !important; cursor: pointer;
}
.kv-vswatch__face {
	width: 100%; height: 100%; border-radius: 100px; overflow: hidden; display: block;
	border: 1px solid var(--kv-grey-900);
	background-size: cover; background-position: center;
}
.kv-vswatch__face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kv-pdp .kv-vswatch[aria-pressed="true"] { border-color: var(--kv-text) !important; }
/* A sibling swatch is a link, not a control, so it says where you are with
   aria-current rather than aria-pressed. Same ring either way. */
.kv-pdp .kv-vswatch[aria-current="page"] { border-color: var(--kv-text) !important; }
.kv-pdp a.kv-vswatch { text-decoration: none; }
.kv-vrow--siblings { display: flex; flex-direction: column; gap: 8px; margin: 0 0 24px; }
.kv-vrow__label {
	display: block; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text-2); font-weight: var(--kv-weight);
}
.kv-pdp .kv-vswatch:hover { border-color: var(--kv-primary) !important; }
.kv-pdp .kv-vswatch[disabled] { opacity: 0.35; cursor: default; }
/* Sold out is not the same as unavailable. A disabled circle is a combination
   that does not exist and is faded to a third; this one exists and is simply
   gone, so it keeps its colour under the same wash a sold-out card wears and
   stays pressable, because pressing it is how the waiting list is reached. */
.kv-pdp .kv-vswatch.is-sold-out { cursor: pointer; }
.kv-vswatch__face { position: relative; }
.kv-pdp .kv-vswatch.is-sold-out .kv-vswatch__face::after {
	content: ""; position: absolute; inset: 0; border-radius: 100px;
	background: var(--kv-overlay-white-60); pointer-events: none;
}
/* The select stays for keyboards and for anyone without JavaScript. */
.kv-pdp tr.kv-has-swatches .kv-vhidden {
	position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
}

/* Size and quantity share a row, node 2:25619 */
/* Both labels on one line, both controls the same height under them. */
.kv-controls { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
.kv-controls .kv-field { display: flex; flex-direction: column; gap: 8px; }
.kv-controls .kv-field label,
.kv-controls .kv-qty__label { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-controls .kv-field > td,
.kv-controls .kv-field > .value { display: block; width: 160px; padding: 0; }
.kv-controls .kv-field > td > select,
.kv-controls .kv-field > .value > select { height: 40px; display: block; }
.kv-pdp .reset_variations { display: none !important; }  /* picking another value is the reset */
.kv-pdp .woocommerce-variation-add-to-cart {
	grid-template-areas: "controls controls" "submit wish";
}
.kv-pdp .woocommerce-variation-add-to-cart .kv-controls { grid-area: controls; }

/* The chosen variation is sold out. The waiting list button takes the add to
   cart button's own cell, and the two things that have nothing left to do go
   away: the button it replaces, and the quantity, because there is no number
   to pick. The attribute controls stay, since choosing another colour is the
   other thing a reader might want. */
.kv-pdp .kv-pdp__wait { grid-area: submit; }
.kv-pdp__buy.is-wait .woocommerce-variation-add-to-cart button[type="submit"],
.kv-pdp__buy.is-wait .kv-controls .kv-field--qty { display: none; }

/* The returns line steps down from 1024, node 2:23782. The frame keeps Body 1
   at 834, but the Norwegian sentence is longer than the English and would take
   a second line there and a third at 768; Body 2 holds it to one line and the
   box to 60 against the frame's 64. It sits here rather than in the block
   higher up for the same reason as the rules below: the base rule it has to
   beat is written after that block. */
@media (max-width: 1024px) {
	.kv-pdp .kv-pdp__returns { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
}

/* The buy row on a phone, nodes 2:23692 to 2:23720: the labels step down to
   Body 2, the controls to 36 and the button and the heart to 48. These sit
   after the rules above rather than in the product block higher up the file,
   because they have to outrank them and specificity alone would not. */
@media (max-width: 767px) {
	.kv-pdp table.variations label,
	.kv-pdp .kv-controls .kv-field label,
	.kv-pdp .kv-controls .kv-qty__label,
	.kv-pdp .kv-pdp__colour p { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp .variations select,
	.kv-pdp .kv-controls select { padding: 7px 31px 7px 11px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp .kv-controls .kv-field > td > select,
	.kv-pdp .kv-controls .kv-field > .value > select { height: 36px; }
	.kv-pdp .kv-qty__step,
	.kv-pdp .kv-qty__step:hover,
	.kv-pdp .kv-qty__step:focus { width: 20px; height: 20px; flex: 0 0 20px; }
	.kv-pdp .kv-qty__step .karivarah-icon { width: 16px; height: 16px; }
	.kv-pdp__buy .quantity { padding: 7px 11px; }
	.kv-pdp__buy .quantity .qty { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pdp .kv-pdp__buy button[type="submit"],
	.kv-pdp .kv-pdp__buy button[type="submit"]:hover { min-height: 48px; padding: 12px 24px !important; }
	.kv-pdp .kv-pdp__wish,
	.kv-pdp .kv-pdp__wish:hover,
	.kv-pdp .kv-pdp__wish:focus { flex: 0 0 48px; width: 48px; min-height: 48px; }
	.kv-pdp .woocommerce-variation-add-to-cart,
	.kv-pdp__buy form.cart:not(.variations_form) { grid-template-columns: minmax(0, 1fr) 48px; }
}

/* WooCommerce writes the price with a note for screen readers; it is not for
   the page. The standard pattern, since the parent theme does not cover it. */
.screen-reader-text {
	position: absolute !important;
	width: 1px; height: 1px;
	margin: -1px; padding: 0; border: 0;
	overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Notifications, nodes 2:34294 and 1:3092
   ------------------------------------------------------------------------ */

.kv-notes { display: flex; flex-direction: column; gap: 8px; margin-bottom: 24px; }
.kv-note {
	display: flex; align-items: center; gap: 8px;
	padding: 16px; border-radius: 12px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-note__icon { width: 24px; height: 24px; flex: 0 0 24px; }
.kv-note__text { flex: 1 1 auto; min-width: 0; }

/* The cross, on the notices that stay. The floating message takes itself away
   after six seconds and carries none.

   Neither notification frame draws one, 2:34294 or 1:3092, so the press is the
   design system's own close control rather than something invented for this:
   the pop-up's, at 2:34300, which is 40 by 40 with the icon 24 and centred in
   it, in Text/Secondary. Everything here but the position comes from there.

   The position is the end of the notice's own row, and the negative margins
   are what let it be both: the press stays 40 square while its margin box is
   24, so the notice keeps the height it is drawn at, and the icon lands on the
   text's own right edge whatever the padding is. Pulling the icon's edge to
   the padding is why the right margin is there rather than only the vertical
   pair. */
.kv-note__close {
	flex: 0 0 auto;
	width: 40px; height: 40px; margin: -8px -8px -8px 0;
	display: grid; place-items: center;
	padding: 0; border: 0; background: none; cursor: pointer;
	color: var(--kv-text-2);
}
.kv-note__close .karivarah-icon { width: 24px; height: 24px; }
.kv-note__close:hover,
.kv-note__close:focus-visible { color: var(--kv-text); }
.kv-note--small .kv-note__close .karivarah-icon { width: 20px; height: 20px; }
.kv-note a { color: var(--kv-text) !important; text-decoration: underline; }
.kv-note a:hover { color: var(--kv-primary) !important; }

.kv-note--success { background: rgba(75, 181, 67, 0.08); }
/* The icons are Text/Primary on both, not the frames' green and red (the
   client, 16.10.2026, a deliberate departure from 2:34294 and 1:3092). The
   tinted ground still tells success from failure. */
.kv-note--success .kv-note__icon { color: var(--kv-text); }

.kv-note--error,
.kv-note--notice,
.kv-note--info { background: rgba(239, 71, 33, 0.08); padding: 12px; }
.kv-note--error .kv-note__icon,
.kv-note--notice .kv-note__icon,
.kv-note--info .kv-note__icon { color: var(--kv-text); }

/* The tighter variant, node 1:3098 */
.kv-note--small {
	gap: 6px; padding: 12px; border-radius: 10px;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
}
.kv-note--small .kv-note__icon { width: 20px; height: 20px; flex-basis: 20px; }

/* WooCommerce's own buttons inside a notice, such as View cart. The kit dresses
   every .button, so this says plainly that here it is a link. */
.kv-note .button,
.kv-note .wc-forward,
.kv-note .button:hover,
.kv-note .wc-forward:hover {
	margin-left: auto; flex: 0 0 auto;
	padding: 0 !important; border: 0 !important; border-radius: 0 !important;
	background: none !important; box-shadow: none !important;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); font-weight: var(--kv-weight);
	color: var(--kv-text) !important; text-decoration: underline;
}
.kv-note .button:hover,
.kv-note .wc-forward:hover { color: var(--kv-primary) !important; }

/* ---------------------------------------------------------------------------
   Cart, nodes 2:26969 (1440), 2:27178 (834) and 2:27341 (375).
   Empty at 2:35112, discount panel open at 2:27162, pop-up at 2:34291.
   ------------------------------------------------------------------------ */

.kv-cart { max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter); }
.kv-cart__grid {
	max-width: 1136px; margin: 0 auto;
	display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 64px; align-items: start;
}
.kv-cart__items { min-width: 0; display: flex; flex-direction: column; gap: 32px; }

.kv-cart__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.kv-cart__title { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text); }
.kv-cart__count { margin: 0; min-width: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); text-align: right; }

.kv-cart__rows { display: flex; flex-direction: column; gap: 20px; }

.kv-cart__note { margin: 0; display: flex; align-items: flex-start; gap: 6px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-cart__note .karivarah-icon { width: 24px; height: 24px; color: var(--kv-text-2); }

/* One row, node 2:26979, used by the page and the pop-up alike */
.kv-cartrow { display: flex; align-items: center; gap: 16px; }
.kv-cartrow.is-busy { opacity: .55; pointer-events: none; }
.kv-cartrow__media { flex: 0 0 150px; width: 150px; height: 150px; border-radius: 12px; overflow: hidden; background: var(--kv-paper); display: block; }
.kv-cartrow__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.kv-cartrow__body { flex: 1 1 auto; min-width: 0; align-self: stretch; display: flex; flex-direction: column; justify-content: space-between; padding: 4px 0; }
.kv-cartrow__text { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* Nodes 2:27094 and 2:27269 put every part of a row at a fixed height against
   the picture: the name at 4, the choices at 58, Remove at 122, the stepper at
   4 and the price ending at 146. That only holds if the name always takes its
   two lines and the choices always take their two, so both are given the
   height they are drawn at whatever they carry. */
.kv-cartrow__title {
	height: 48px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); text-decoration: none;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.kv-cartrow__title:hover { color: var(--kv-primary); }
.kv-cartrow__meta { height: 50px; display: flex; flex-direction: column; gap: 2px; overflow: hidden; }
.kv-cartrow__metaline { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kv-cartrow__remove {
	align-self: flex-start; display: inline-flex; align-items: center; gap: 4px;
	padding: 0; border: 0; background: none; cursor: pointer;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2);
}
.kv-cartrow__remove .karivarah-icon { width: 24px; height: 24px; min-width: 0; min-height: 0; }
.kv-cartrow__remove:hover { color: var(--kv-primary); }
.kv-cartrow__side { flex: 0 0 auto; align-self: stretch; display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between; padding: 4px 0; }

.kv-cartqty {
	display: flex; align-items: center; gap: 12px; width: 114px;
	padding: 7px 11px; border: 1px solid var(--kv-grey-600); border-radius: 8px;
}
.kv-cartqty__step { display: inline-flex; padding: 0; border: 0; background: none; cursor: pointer; color: var(--kv-text); }
.kv-cartqty__step .karivarah-icon { width: 24px; height: 24px; }
.kv-cartqty__step[disabled] { color: var(--kv-text-disabled); cursor: default; }
.kv-cartqty__count { flex: 1 1 auto; text-align: center; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }

.kv-cartrow__price { text-align: right; white-space: nowrap; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-cartrow__price.is-sale { color: var(--kv-primary); }
.kv-cartrow__was { display: block; color: var(--kv-text-2); text-decoration: line-through; }
.kv-cartrow__price .woocommerce-Price-amount { font-size: inherit; line-height: inherit; color: inherit; }

/* A line that can no longer be bought: sold while it sat there, or off the
   shop. It keeps its place in the list, at the foot of it, under a heading of
   its own, and the group is a section named by that heading so the fade is
   not the only thing that says why these rows are different.

   The fade is the one a sold-out card carries, the same 60% white wash over
   the picture, and it is on the picture alone. The type steps back to the
   secondary colour instead, which is the colour the choices under every name
   are already set in, so nothing in the row drops below the contrast the rest
   of the page holds. `border-radius: inherit` because the picture is 12 on
   the page and 8 on a phone and the wash should not have to know. */
.kv-cart__notice { max-width: 1136px; margin: 0 auto 32px; }
.kv-cart__gone { display: flex; flex-direction: column; gap: 20px; }
.kv-cart__gonehead { margin: 0; }
/* The empty cart spaces its own heading, and the flex gap does it here. */
.kv-cart--empty .kv-cart__items .kv-cart__head { margin-bottom: 0; }

.kv-cartrow.is-gone .kv-cartrow__media { position: relative; }
.kv-cartrow.is-gone .kv-cartrow__media::after {
	content: ""; position: absolute; inset: 0; border-radius: inherit;
	background: var(--kv-overlay-white-60); pointer-events: none;
}
.kv-cartrow.is-gone .kv-cartrow__price { color: var(--kv-text-2); }

/* The waitlist in the stepper's place. A text control rather than a button,
   because the row already has the only button it is drawn with.

   It takes the site's link behaviour rather than one of its own: the
   secondary colour its neighbour Remove is set in, and the primary on hover,
   which is the rule at the top of this file. Underlined with the same recipe
   prose links use, because Remove has a bin beside it to say it can be
   pressed and this has nothing, and colour alone is not a signal. Primary at
   rest was the first attempt and was wrong twice over: on this site that
   colour means a current or active thing, and it shouted out of a row the
   design had just faded back. */
.kv-cartrow__notify {
	padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text-2);
	text-decoration: underline;
	text-underline-position: from-font;
	text-decoration-skip-ink: none;
}
.kv-cartrow__notify:hover,
.kv-cartrow__notify:focus-visible { color: var(--kv-primary); }
.kv-cartrow__notify[aria-disabled="true"] { color: var(--kv-text-disabled); cursor: default; text-decoration: none; }

/* Summary card, node 2:27024 */
.kv-cart__side { display: flex; flex-direction: column; gap: 24px; }
.kv-sum { background: var(--kv-primary-8); border-radius: 12px; padding: 24px; display: flex; flex-direction: column; gap: 24px; }
.kv-sum__top { display: flex; flex-direction: column; gap: 16px; }
.kv-sum__head { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text); }
.kv-sum__body { display: flex; flex-direction: column; gap: 20px; }
.kv-sum__rule { height: 1px; background: var(--kv-grey-600); }
.kv-sum__rows { display: flex; flex-direction: column; gap: 16px; }
.kv-sum__row { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-sum__row--discount > span:last-child,
.kv-sum__row--free > span:last-child { color: var(--kv-error-dark); }
.kv-sum__row--free > span:last-child strong { font-weight: var(--kv-weight); }
.kv-sum__row--quiet > span:last-child { color: var(--kv-text-2); }
.kv-sum__total { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.kv-sum__totallabel { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-sum__totallabel small { font-weight: var(--kv-weight); font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-sum__totalvalue { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); white-space: nowrap; }

.kv-sum__buttons { display: flex; flex-direction: column; gap: 20px; }
.kv-sum__pay { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.kv-sum__pay p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-sum__pay .kv-marks--pay { gap: 8px; justify-content: center; }

/* The free shipping sentence and bar, node 2:27028 */
.kv-ship { display: flex; flex-direction: column; gap: 16px; }
.kv-ship__text { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-ship__track { height: 6px; border-radius: 1000px; background: var(--kv-primary-12); overflow: hidden; }
.kv-ship__fill { height: 6px; border-radius: 1000px; background: var(--kv-primary-light); transition: width .3s ease; }
/* Once the threshold is passed the rail behind the fill turns Grey/500, node
   1:3277. The fill covers it at that point, so this is for the half second
   the width takes to travel rather than for the resting state. */
.kv-ship.is-earned .kv-ship__track { background: var(--kv-grey-500); }

/* Discount panel, closed 2:27080 and open 2:27162 */
.kv-disc { background: rgba(239, 71, 33, .08); border-radius: 12px; padding: 24px; display: flex; flex-direction: column; gap: 24px; }
.kv-disc__head {
	width: 100%; display: flex; align-items: center; gap: 8px;
	padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-disc__head > span { flex: 1 1 auto; }
.kv-disc__caret { width: 24px; height: 24px; color: var(--kv-text); transition: transform .2s ease; }
.kv-disc.is-open .kv-disc__caret { transform: rotate(180deg); }
.kv-disc__body { display: flex; flex-direction: column; gap: 16px; }
.kv-disc__field { display: flex; align-items: center; gap: 12px; }
/* The medium input field, node 1:1019: a 12 radius rather than a pill, the
   stroke in Text/Secondary like every other field on the site, and the
   stroke out of the padding so the box stands 48 as the frame draws it. */
.kv-disc .kv-disc__input {
	flex: 1 1 auto; min-width: 0; background: none; box-shadow: none;
	/* 44 tall with the stroke inside, node 2:27168. */
	border: 1px solid var(--kv-text-2); border-radius: 12px; padding: 9px 15px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-disc .kv-disc__input::placeholder { color: var(--kv-text-2); opacity: 1; }
/* Focus darkens the stroke, node 1:1016's focused state, which is what the
   shared field already does. The search field is the one that goes Primary. */
.kv-disc .kv-disc__input:focus { outline: none; border-color: var(--kv-text); box-shadow: none; }
.kv-disc__apply {
	flex: 0 0 93px; width: 93px; padding: 0; border: 0; background: none; cursor: pointer;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
	text-align: center; text-decoration: underline;
}
.kv-disc__apply:hover { color: var(--kv-primary); }

/* Empty, node 2:35112 */
/* The empty cart, node 2:35112. WooCommerce prints its own notice above the
   page; the block below says the same thing in the frame's shape, so the
   notice goes. */
.kv-cart--empty .kv-cart__grid { display: block; }
.woocommerce .wc-empty-cart-message { display: none; }
.kv-cart--empty .kv-cart__head { margin-bottom: 32px; }
.kv-cart__empty { display: flex; flex-direction: column; align-items: center; gap: 24px; padding: 64px 0; text-align: center; }
.kv-cart__empty .kv-btn { margin-top: 8px; }
.kv-cart__emptyicon { display: grid; place-items: center; padding: 24px; border-radius: 1000px; background: var(--kv-primary-4); color: var(--kv-primary-light); }
.kv-cart__emptyicon .karivarah-icon { width: 64px; height: 64px; }
.kv-cart__empty p { margin: 0; max-width: 416px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-cart__empty .kv-btn { align-self: center; }

/* The pop-up, node 2:34291 */
.kv-pop { width: 600px; max-width: calc(100% - 32px); padding: 0; border: 0; background: none; overflow: visible; }
.kv-pop::backdrop { background: rgba(0, 0, 0, .4); }
.kv-pop__inner { position: relative; background: var(--kv-paper); border-radius: 12px; display: flex; flex-direction: column; max-height: calc(100vh - 48px); }
.kv-pop__top { position: relative; display: flex; flex-direction: column; gap: 32px; padding: 32px 32px 0; min-height: 0; }
.kv-pop__head { display: flex; flex-direction: column; gap: 24px; }
.kv-pop__close {
	position: absolute; top: 2px; right: 2px; width: 40px; height: 40px;
	display: grid; place-items: center; padding: 0; border: 0; background: none; cursor: pointer; color: var(--kv-text-2);
}
.kv-pop__close:hover { color: var(--kv-text); }
.kv-pop__list {
	display: flex; flex-direction: column; gap: 20px;
	max-height: 265px; overflow-y: auto; padding-right: 18px;
	scrollbar-width: thin; scrollbar-color: var(--kv-grey-700) var(--kv-grey-300);
}
.kv-pop__list::-webkit-scrollbar { width: 6px; }
.kv-pop__list::-webkit-scrollbar-track { background: var(--kv-grey-300); border-radius: 100px; }
.kv-pop__list::-webkit-scrollbar-thumb { background: var(--kv-grey-700); border-radius: 100px; }
.kv-pop__foot {
	border-top: 1px solid var(--kv-grey-500);
	padding: 24px 32px 32px; display: flex; flex-direction: column; align-items: center; gap: 24px;
}
.kv-pop__foot .kv-sum__rows { width: 100%; gap: 12px; }
.kv-pop__foot .kv-sum__rule { background: var(--kv-grey-300); }
.kv-pop__foot .kv-sum__row--discount,
.kv-pop__foot .kv-sum__row--free { color: var(--kv-error-dark); }
.kv-pop__foot .kv-btn { width: 100%; padding: 18px 24px; }
.kv-pop__continue {
	padding: 0; border: 0; background: none; cursor: pointer;
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-primary);
}
.kv-pop__continue:hover,
.kv-pop__continue:focus-visible { color: var(--kv-primary); text-decoration: underline; }
.kv-pop .kv-cart__empty { padding: 32px 0 48px; }
html.kv-pop-open { overflow: hidden; }

/* The floating message: it hugs its sentence at 1440 and 834 (nodes 2:33726
   and 2:33914, both 738 wide) and fills the gutter at 375 (node 2:34109, 343
   wide and three lines deep), always 20 below the header. */
.kv-toast {
	position: fixed; left: 50%; transform: translateX(-50%); z-index: 1000;
	width: max-content; max-width: calc(100% - 32px);
	background: var(--kv-paper); border-radius: 12px;
}

@media (max-width: 767px) {
	.kv-toast { width: calc(100% - 32px); border-radius: 10px; }
	.kv-toast .kv-note { padding: 12px; border-radius: 10px; gap: 6px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-toast .kv-note__icon { width: 20px; height: 20px; flex-basis: 20px; }
}

/* Between the design's two-column frame and its stacked one, the gutter gives
   way first, the way the header's does, so the columns keep their proportions
   as long as they can. */
@media (min-width: 1180px) and (max-width: 1439px) {
	.kv-cart { padding-left: clamp(24px, 10.5vw, 152px); padding-right: clamp(24px, 10.5vw, 152px); }
}

/* 834, and every width where the left column would be too narrow to carry a
   row: 150 of picture, the name, and a 114 stepper leaves nothing under 1180. */
@media (max-width: 1179px) {
	.kv-cart { padding: 64px var(--kv-gutter); }
	/* align-items: start is a cross-axis rule, so a column flex box would size
	   both halves to their content instead of the gutter. */
	.kv-cart__grid { display: flex; flex-direction: column; align-items: stretch; gap: 64px; }
	.kv-sum__buttons { flex-direction: row; gap: 24px; }
	.kv-sum__buttons .kv-btn { flex: 1 1 0; }
}

/* 375 */
@media (max-width: 767px) {
	.kv-cart { padding: 36px var(--kv-gutter); }
	.kv-cart__grid { gap: 32px; }
	.kv-cart__items { gap: 24px; }
	.kv-cart__head { gap: 8px; }
	.kv-cart__count { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cart__rows { gap: 16px; }
	.kv-cart__note { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cart__note .karivarah-icon { width: 20px; height: 20px; }

	/* Node 2:27351: the picture on the left, and the name, the choices, Remove
	   and then the stepper beside the price filling the column next to it. */
	.kv-cartrow {
		display: grid; grid-template-columns: 120px minmax(0, 1fr);
		column-gap: 12px; row-gap: 8px; align-items: start;
	}
	.kv-cartrow__media { grid-column: 1; grid-row: 1 / span 2; flex-basis: 120px; width: 120px; height: 120px; border-radius: 8px; }
	.kv-cartrow__body { grid-column: 2; grid-row: 1; padding: 0; gap: 8px; justify-content: flex-start; }
	.kv-cartrow__text { gap: 4px; }
	/* Node 2:27534: name 0, choices 44, Remove 94, stepper and price 122. */
	.kv-cartrow__title { height: 40px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cartrow__meta { height: 42px; }
	.kv-cartrow__metaline { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cartrow__remove { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); gap: 2px; }
	.kv-cartrow__remove .karivarah-icon { width: 20px; height: 20px; }

	/* The stepper and the price share the row under the name */
	.kv-cartrow__side {
		grid-column: 2; grid-row: 2; align-self: auto; padding: 0; min-height: 40px;
		flex-direction: row; align-items: center; justify-content: space-between;
	}
	.kv-cartqty { width: auto; gap: 6px; padding: 5px; border-radius: 6px; }
	.kv-cartqty .karivarah-icon { width: 20px; height: 20px; }
	.kv-cartqty__count { flex: 0 0 auto; min-width: 10px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cartrow__price { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cartrow__notify { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-cart__notice { margin-bottom: 24px; }
	.kv-cart__gone { gap: 16px; }

	.kv-sum { padding: 16px; gap: 20px; }
	.kv-sum__head { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-sum__rows { gap: 12px; }
	.kv-sum__row { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-sum__row--discount { color: var(--kv-error-dark); }
	.kv-sum__totallabel { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); gap: 8px; }
	.kv-sum__totallabel small { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
	.kv-sum__totalvalue { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-sum__buttons { flex-direction: column; gap: 16px; }
	/* Site-wide, not the cart's alone: every .kv-btn on a phone takes this size.
	   It sits here for history, and stays here because moving it would change
	   which later rules it beats. The button's own section points back here. */
	.kv-btn { padding: 12px 20px; border-radius: 12px; font-size: var(--kv-fs-body1); min-height: 48px; }
	.kv-sum__pay { gap: 12px; }
	.kv-sum__pay p { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-sum__pay .kv-marks svg { height: 20px; }

	.kv-ship { gap: 12px; }
	.kv-ship__text { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-disc { padding: 24px; }
	.kv-disc__head { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-disc__caret { width: 20px; height: 20px; }
	.kv-disc.is-open { padding: 16px; gap: 20px; }
	.kv-disc__body { gap: 12px; }
	.kv-disc .kv-disc__input { border-color: var(--kv-text-2); border-radius: 10px; padding: 11px 15px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-disc__apply { flex-basis: 82px; width: 82px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	/* Node 2:35323: 24 under the heading, 16 under the mark, 32 above the
	   button, and the block sits on 48. */
	.kv-cart--empty .kv-cart__head { margin-bottom: 24px; }
	.kv-cart__empty { gap: 16px; padding: 48px 0; }
	.kv-cart__empty .kv-btn { margin-top: 16px; }
	.kv-cart__emptyicon { padding: 16px; }
	.kv-cart__emptyicon .karivarah-icon { width: 48px; height: 48px; }
	.kv-cart__empty p { max-width: 247px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-pop { max-width: calc(100% - 32px); }
	.kv-pop__top { padding: 32px 16px 0; }
	.kv-pop__head { gap: 16px; }
	.kv-pop__close { top: -3px; right: -3px; }
	.kv-pop__list { gap: 16px; padding-right: 14px; }
	.kv-pop .kv-note { padding: 12px; border-radius: 10px; gap: 6px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-pop .kv-note__icon { width: 20px; height: 20px; }
	.kv-pop__foot { padding: 16px 16px 24px; gap: 24px; }
	.kv-pop__foot .kv-sum__rows { gap: 8px; }
	.kv-pop__foot .kv-btn { min-height: 52px; padding: 12px 24px 12px 20px; border-radius: 12px; font-size: var(--kv-fs-body1); }
	.kv-pop__continue { font-size: var(--kv-fs-body1); }
}

/* The cart page is a plain WordPress page, so the parent theme's container
   would box it in at 1140. The gutter and the width belong to .kv-cart, as
   they do on every template the theme owns. */
body.woocommerce-cart .site-main,
body.woocommerce-checkout .site-main,
body.kv-theme-page .site-main { max-width: none; margin: 0; padding: 0; }
body.woocommerce-cart .page-content,
body.kv-theme-page .page-content { margin: 0; }

/* Elementor's kit styles headings and links more specifically than a bare
   class, so the cart states its own type and colour at two classes deep. */
.kv-cart .kv-cart__title { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); font-weight: var(--kv-weight-semibold); }
/* One step under the page's own heading, and it follows it down. */
.kv-cart .kv-cart__gonehead { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); font-weight: var(--kv-weight-semibold); color: var(--kv-text); }
.kv-cart .kv-cartrow.is-gone .kv-cartrow__title { color: var(--kv-text-2); }
.kv-cart .kv-sum__head,
.kv-pop .kv-sum__head { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); font-weight: var(--kv-weight-semibold); }
.kv-cart .kv-cartrow__title,
.kv-pop .kv-cartrow__title { color: var(--kv-text); text-decoration: none; }
.kv-cart .kv-cartrow__title:hover,
.kv-pop .kv-cartrow__title:hover { color: var(--kv-primary); }
.kv-cart .kv-cartrow__media,
.kv-pop .kv-cartrow__media { text-decoration: none; }

@media (max-width: 1179px) {
	.kv-cart .kv-cart__title { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
	.kv-cart .kv-cart__gonehead { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
}

@media (max-width: 767px) {
	.kv-cart .kv-cart__title { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-cart .kv-cart__gonehead { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-cart .kv-sum__head { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
}

/* An applied code reads as its own summary line, with the cross that lifts it. */
.kv-sum__code { display: inline-flex; align-items: center; gap: 6px; }
.kv-sum__off { display: inline-flex; padding: 0; border: 0; background: none; cursor: pointer; color: var(--kv-text-2); }
.kv-sum__off .karivarah-icon { width: 16px; height: 16px; }
.kv-sum__off:hover { color: var(--kv-primary); }

/* ---------------------------------------------------------------------------
   No touch highlight, anywhere.

   The browser paints a translucent blue box over whatever is tapped, which is
   not in the palette and fires on every link, button, summary and field. A
   control shows it is being used through its own colour, border or position,
   the way the frames draw it. Keyboard focus is a different thing and stays.
   ------------------------------------------------------------------------ */

html,
a, button, summary, label,
input, select, textarea,
[role="button"], [tabindex],
.elementor-element, .elementor-item { -webkit-tap-highlight-color: transparent; }

/* A control is not prose: tapping one twice should work it, not select its
   label, which the browser paints in the reader's own accent colour. Text the
   visitor might want to copy, product names, prices, descriptions, stays
   selectable. */
button, summary, [role="button"],
.kv-btn, .kv-cartrow__remove, .kv-cartqty, .kv-disc__head, .kv-disc__apply,
.kv-pop__close, .kv-pop__continue, .kv-sum__off,
.kv-page, .kv-dot, .kv-vswatch, .kv-swatch,
.kv-nav .elementor-item, .kv-lang__current, .kv-iconlink {
	-webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}

/* ---------------------------------------------------------------------------
   Form fields, nodes 2:27728 at rest, 2:27930 once filled, 2:28137 when wrong.

   The label never disappears. At rest it sits where the value will go; once
   the field has focus or holds anything it shrinks to 12/16 and rises to the
   top of the box. The box keeps its height either way, so nothing shifts.

   On a phone every field is resized by a rule in the contact page's 767px
   block, marked "Site-wide".
   ------------------------------------------------------------------------ */

.kv-field { display: flex; flex-direction: column; gap: 4px; }
.kv-field__box { position: relative; display: block; }
.kv-field .kv-field__input {
	width: 100%; display: block; margin: 0; box-sizing: border-box;
	padding: 15px 20px; border: 1px solid var(--kv-text-2); border-radius: 16px;
	background: none; box-shadow: none;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
	transition: border-color .15s, padding .15s;
}
.kv-field .kv-field__input:focus { outline: none; border-color: var(--kv-text); box-shadow: none; }
.kv-field__label {
	position: absolute; left: 20px; top: 16px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2);
	pointer-events: none; transition: transform .15s, font-size .15s, line-height .15s;
	transform-origin: left top; background: none;
}
/* Focused, or holding something: the label rises and the value moves down to
   meet it, which is why the padding changes with it. */
.kv-field__input:focus + .kv-field__label,
.kv-field__input:not(:placeholder-shown) + .kv-field__label,
.kv-field__input:not(:empty) + .kv-field__label { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); transform: translateY(-11px); }
/* The box keeps its 56: what the label takes off the top, the value gives back. */
.kv-field .kv-field__input:focus,
.kv-field .kv-field__input:not(:placeholder-shown) { padding-top: 21px; padding-bottom: 9px; }

.kv-field.kv-field--area .kv-field__input { min-height: 152px; resize: vertical; }
.kv-field--area .kv-field__label { top: 16px; }

/* The footer's field at tablet, node 1:1988: the small size, 44 tall on a
   14/20 value with 12 and 16 of padding and a 10 radius. The rising label
   moves with it, and the box keeps its height either way. */
@media (min-width: 768px) and (max-width: 1024px) {
	.kv-footer .kv-field .kv-field__input {
		padding: 11px 15px; border-radius: var(--kv-btn-radius-sm);
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-field__label {
		left: 16px; top: 12px;
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-footer .kv-field__input:focus + .kv-field__label,
	.kv-footer .kv-field__input:not(:placeholder-shown) + .kv-field__label { transform: translateY(-9px); }
	.kv-footer .kv-field .kv-field__input:focus,
	.kv-footer .kv-field .kv-field__input:not(:placeholder-shown) { padding-top: 17px; padding-bottom: 5px; }
}

.kv-field.is-wrong .kv-field__input { border-color: var(--kv-error) !important; color: var(--kv-error-dark); }
.kv-field.is-wrong .kv-field__label { color: var(--kv-error-dark); }
.kv-field__error { margin: 0; font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); color: var(--kv-error-dark); }

/* A checkbox and its sentence, node 2:27733 */
.kv-check { display: flex; align-items: flex-start; gap: 8px; }
.kv-check input {
	flex: 0 0 16px; width: 16px; height: 16px; margin: 2px 0 0; appearance: none; cursor: pointer;
	border: 1px solid var(--kv-text); border-radius: 3px; background: none;
}
/* Node 1:1814 fills a ticked box with Primary/Main and not the ink. It had
   been filling with Text/Primary, which reads as a disabled control rather
   than a chosen one. */
.kv-check input:checked {
	border-color: var(--kv-primary);
	background: var(--kv-primary) center / 11px no-repeat
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
}
/* And the hover the same node draws: a 2px ring in Grey/500 outside the box,
   which is a shadow rather than a border so nothing moves under the pointer. */
.kv-check input:hover { box-shadow: 0 0 0 2px var(--kv-grey-500); }
/* The frame also fills an empty box with Paper under the pointer, node
   1:1819, which only shows where the box stands on a tint. A ticked box
   keeps its Primary fill. */
.kv-check input:not(:checked):hover { background-color: var(--kv-paper); }
.kv-check input:focus-visible { outline: 2px solid var(--kv-primary); outline-offset: 2px; }

/* A radio in the same family: the same ink, the same ring, round rather than
   square, and a dot rather than a tick. The style guide draws no radio, so it
   is the checkbox with its corners taken off.

   The overlay card gives every box in it a 4px radius, and that rule is two
   classes deep and later in the file, so the round one has to say where it is
   as well or it comes out square. */
.kv-check input[type="radio"],
.kv-overlay__card .kv-check input[type="radio"] { border-radius: 100px; }
.kv-check input[type="radio"]:checked {
	border-color: var(--kv-primary);
	background: radial-gradient(circle at center, var(--kv-primary) 0 45%, var(--kv-paper) 47%);
}
.kv-check input[disabled] { cursor: default; opacity: .4; }
.kv-check input[disabled]:hover { box-shadow: none; }
.kv-check:has(input[disabled]) label,
.kv-check:has(input[disabled]) > span { cursor: default; color: var(--kv-text-disabled); }
.kv-check label { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text); cursor: pointer; }
.kv-check.is-wrong input { border-color: var(--kv-error); }

/* The field no person sees */
.kv-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------------------------------------------------------------------------
   Contact page, nodes 2:27710 (1440), 2:27778 (834), 2:27847 (375)
   ------------------------------------------------------------------------ */

.kv-contactpage { max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter); }
.kv-contactpage > * { max-width: 1136px; margin-inline: auto; }
.kv-contactpage__intro { display: flex; flex-direction: column; gap: 24px; max-width: 592px; margin-inline: 0; }
.kv-contactpage__eyebrow { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-primary); }
.kv-contactpage__said { display: flex; flex-direction: column; gap: 24px; }
.kv-contactpage .kv-contactpage__said h1 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-contactpage__said p { margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }

.kv-contactpage__row { display: flex; align-items: flex-start; gap: 64px; margin-top: 48px; }

.kv-contactpage__card {
	flex: 1 1 auto; min-width: 0;
	background: var(--kv-primary-8); border-radius: 24px; padding: 32px;
	display: flex; flex-direction: column; gap: 32px;
}
.kv-contactpage__head { display: flex; flex-direction: column; gap: 20px; }
.kv-contactpage .kv-contactpage__head h2 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text); }
.kv-contactpage__head p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-contactpage__form { display: flex; flex-direction: column; gap: 32px; }
.kv-contactpage__fields { display: flex; flex-direction: column; gap: 24px; }
.kv-contactpage__checks { display: flex; flex-direction: column; gap: 12px; }
.kv-contactpage .kv-contactpage__send { align-self: flex-start; }
.kv-contactpage__card--sent { justify-content: center; }

.kv-contactpage__aside { flex: 0 0 480px; width: 480px; display: flex; flex-direction: column; gap: 32px; }
.kv-contactpage__illustration { display: block; width: 100%; height: auto; border-radius: 5px; }
.kv-contactpage__details { display: flex; flex-direction: column; gap: 24px; }
.kv-contactpage__detail { display: flex; flex-direction: column; gap: 10px; }
.kv-contactpage__label { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-contactpage__value { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }

.kv-contactpage .kv-contactpage__social { display: flex; gap: 16px; margin: 0; padding: 0; list-style: none; }
.kv-contactpage .kv-contactpage__social a {
	display: grid; place-items: center; width: 48px; height: 48px; border-radius: 100px;
	background: var(--kv-primary-8); color: var(--kv-text);
}
.kv-contactpage .kv-contactpage__social .kv-social__icon { width: 28px; height: 28px; }

/* 834 */
@media (max-width: 1179px) {
	.kv-contactpage { padding: 64px var(--kv-gutter); }
	.kv-contactpage__intro { max-width: 527px; gap: 20px; }
	.kv-contactpage .kv-contactpage__said h1 { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	.kv-contactpage__said { gap: 20px; }
	.kv-contactpage__said p { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	.kv-contactpage__row { gap: 24px; margin-top: 48px; }
	.kv-contactpage__card { padding: 24px; gap: 24px; }
	.kv-contactpage .kv-contactpage__head h2 { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
	.kv-contactpage__fields { gap: 20px; }
	/* 48 fields and a 144 box, stroke inside, nodes 2:27797 and 2:27800. */
	.kv-contactpage .kv-field .kv-field__input { padding: 11px 19px; }
	.kv-contactpage .kv-field--area .kv-field__input { min-height: 144px; }
	.kv-contactpage__aside { flex-basis: 240px; width: 240px; }
	.kv-contactpage .kv-contactpage__social a { width: 48px; height: 48px; }
}

/* 375: the illustration leads, the card runs to the edges */
@media (max-width: 767px) {
	/* The illustration leads and the details close the page, node 2:27850.
	   `order` needs a flex parent; without one the page kept source order. */
	.kv-contactpage { display: flex; flex-direction: column; padding: 0 0 36px; }
	.kv-contactpage > * { max-width: none; }
	.kv-contactpage__row { display: contents; }
	.kv-contactpage__aside { display: contents; }
	.kv-contactpage__illustration { order: -2; width: 320px; max-width: calc(100% - 32px); margin: 0 auto; }
	.kv-contactpage__intro { order: -1; max-width: none; padding: 32px var(--kv-gutter) 0; gap: 16px; }
	.kv-contactpage__eyebrow { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-contactpage .kv-contactpage__said h1 { font-size: 28px; line-height: 40px; }
	.kv-contactpage__said { gap: 16px; }
	.kv-contactpage__said p { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }

	.kv-contactpage__card { order: 1; border-radius: 0; padding: 24px var(--kv-gutter); gap: 24px; }
	.kv-contactpage .kv-contactpage__head h2 { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-contactpage__head { gap: 16px; }
	.kv-contactpage__fields { gap: 16px; }
	/* The send button keeps the large size here, node 2:27877, where the rest
	   of the phone's buttons step down. */
	.kv-contactpage .kv-contactpage__send {
		align-self: stretch;
		min-height: 56px; padding: var(--kv-btn-pad-lg); border-radius: var(--kv-btn-radius-lg);
		font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
	}
	/* 44 fields, stroke inside, node 2:27864. */
	.kv-contactpage .kv-field .kv-field__input { padding: 11px 15px; }

	.kv-contactpage__details { order: 2; padding: 24px var(--kv-gutter) 0; gap: 16px; }
	.kv-contactpage__detail { gap: 6px; }
	.kv-contactpage__label, .kv-contactpage__value { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-contactpage .kv-contactpage__social a { width: 40px; height: 40px; }
	.kv-contactpage .kv-contactpage__social .kv-social__icon { width: 24px; height: 24px; }

	/* Site-wide, not the contact page's alone: every field on a phone takes
	   this size. Kept here so it keeps beating the rules it beats today; the
	   field's own section points back here. */
	.kv-field .kv-field__input { padding: 10px 16px; border-radius: 12px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-field__label { left: 16px; top: 10px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-field__input:focus + .kv-field__label,
	.kv-field__input:not(:placeholder-shown) + .kv-field__label { font-size: 11px; line-height: 14px; transform: translateY(-7px); }
	.kv-field .kv-field__input:focus,
	.kv-field .kv-field__input:not(:placeholder-shown) { padding-top: 16px; padding-bottom: 4px; }
	.kv-field.kv-field--area .kv-field__input { min-height: 124px; }
}

/* The newsletter uses the shared field as it is drawn, node
   I2:27777;23752:140723: no fill, a 1px #6A6A6A stroke, 16 radius, and the
   placeholder in the same grey. All of that is already the shared field, so
   nothing here restates it. The field fills the row it is in, which on a phone
   is the whole width.

   The one thing the footer does change is the colour of what a customer types.
   The shared field writes in --kv-text, which is near black and was legible
   while this box carried a white fill. Against the dark footer it would not be,
   so the value takes the colour the rest of the footer already uses. */
.kv-signup { align-items: stretch; }
/* No basis of its own: the field takes whatever the button leaves on the
   line. A 200 basis read as a minimum while the row is allowed to wrap, so
   the moment the column fell under 373 the button dropped to a line of its
   own instead of the field giving way. The frames keep them side by side at
   every width, nodes 1:1835, 1:1987 and 1:2140. */
.kv-signup .kv-field { flex: 1 1 0; min-width: 0; }
.kv-signup .kv-field .kv-field__input { color: var(--kv-page); }
.kv-signup .kv-field .kv-field__input:focus { border-color: var(--kv-primary); }

/* The star on a required field, in the error colour so it reads as a condition
   rather than as decoration. */
.kv-required { color: var(--kv-error-dark); }
/* The answer sits on its own line under the field, and wears the paper
   background so it reads against the dark footer. */
.kv-signup { flex-wrap: wrap; }
.kv-signup__notice { flex: 1 0 100%; width: 100%; }
.kv-signup__notice:empty { display: none; }
.kv-signup__notice .kv-note { background: var(--kv-paper); }

/* The phone keeps the row too, so the field fills it there as well. */

/* ---------------------------------------------------------------------------
   FAQ page, nodes 2:28321 (1440), 2:28477 (834) and 2:28634 (375)
   ------------------------------------------------------------------------ */

.kv-faq { max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter); }
.kv-faq > * { max-width: 1136px; margin-inline: auto; }
.kv-faq__intro { display: flex; flex-direction: column; gap: 16px; max-width: 607px; margin-inline: 0; }
.kv-faq .kv-faq__intro h1 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-faq__lead { margin: 8px 0 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }

.kv-faq__row { display: flex; align-items: flex-start; gap: 64px; margin-top: 64px; }
.kv-faq__groups { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 24px; }

/* One group, node 2:28398 closed and 2:28335 open */
/* The stroke comes out of the padding, node 2:28335: a closed card holds 96. */
.kv-faq__group { border: 1px solid var(--kv-grey-600); border-radius: 12px; padding: 23px; }
.kv-faq__head {
	display: flex; align-items: center; gap: 16px; cursor: pointer; list-style: none;
	font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text);
}
.kv-faq__head::-webkit-details-marker { display: none; }
.kv-faq__title { flex: 1 1 auto; min-width: 0; }
.kv-faq .kv-faq__icon { width: 48px; height: 48px; flex: 0 0 48px; }
.kv-faq .kv-faq__caret { width: 32px; height: 32px; flex: 0 0 32px; color: var(--kv-text); transition: transform .2s ease; }

.kv-faq__body { margin-top: 24px; }
.kv-faq__item { display: flex; flex-direction: column; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--kv-grey-400); }
.kv-faq .kv-faq__q { margin: 0; font-weight: var(--kv-weight); font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }
.kv-faq__a { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
/* An answer that runs to more than one paragraph, spaced the way the home
   page's four questions space theirs. A single paragraph answer is unchanged,
   because its only paragraph is also its last. */
.kv-faq__a p { margin: 0 0 8px; }
.kv-faq__a p:last-child { margin-bottom: 0; }

/* The two cards beside, node 2:28458 */
.kv-faq__aside { flex: 0 0 360px; width: 360px; display: flex; flex-direction: column; gap: 28px; }
.kv-faq__card {
	position: relative; isolation: isolate; overflow: hidden;
	background: var(--kv-primary-8); border-radius: 12px; padding: 24px;
	display: flex; flex-direction: column; align-items: flex-start; gap: 24px;
}
.kv-faq__card::before {
	content: ""; position: absolute; inset: 0; z-index: -1;
	background: url("assets/brand/veins.svg") center / cover no-repeat;
	pointer-events: none;
}
.kv-faq__cardtext { display: flex; flex-direction: column; gap: 12px; }
.kv-faq__cardhead { margin: 0; font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-faq__cardbody { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-faq .kv-faq__card .kv-btn { padding: 12px 20px; border-radius: 12px; font-size: var(--kv-fs-body1); }
.kv-faq .kv-faq__card .kv-btn--secondary { border-width: 1.2px; }

@media (max-width: 1179px) {
	.kv-faq { padding: 64px var(--kv-gutter); }
	/* Stacked, align-items is the cross axis again, so both halves would size
	   to their content instead of the gutter. */
	.kv-faq__row { flex-direction: column; align-items: stretch; gap: 48px; margin-top: 48px; }
	.kv-faq__aside { flex-basis: auto; width: 100%; flex-direction: row; gap: 16px; }
	.kv-faq__card { flex: 1 1 0; padding: 20px; }
	.kv-faq .kv-faq__intro h1 { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
}

@media (max-width: 767px) {
	.kv-faq { padding: 36px var(--kv-gutter); }
	.kv-faq .kv-faq__intro h1 { font-size: 28px; line-height: 40px; }
	/* 16 under the heading on a phone, node 2:28645, where 1440 and 834 give
	   24. With the eyebrow gone the heading carries the gap on its own. */
	.kv-faq__lead { margin-top: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-faq__row { gap: 32px; margin-top: 32px; }
	.kv-faq__groups { gap: 16px; }
	.kv-faq__group { padding: 11px; }
	.kv-faq__head { gap: 12px; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-faq .kv-faq__icon { width: 32px; height: 32px; flex-basis: 32px; }
	.kv-faq .kv-faq__caret { width: 24px; height: 24px; flex-basis: 24px; }
	.kv-faq__body { margin-top: 16px; }
	/* The small accordion row, node 1:2936: 12 above and below and 12
	   between the question and its answer. */
	.kv-faq__item { padding: 12px 0; gap: 12px; }
	.kv-faq .kv-faq__q { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	.kv-faq__a { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	/* Stacked again, so the basis that shared the row would become a height. */
	.kv-faq__aside { flex-direction: column; gap: 16px; }
	.kv-faq__card { flex: 0 0 auto; padding: 20px; }
}

/* Links inside the contact page's lead and its details, which the design draws
   in the body colour: underlined so they read as links, orange on hover. */
.kv-contactpage .kv-contactpage__said a,
.kv-contactpage .kv-contactpage__value a { color: var(--kv-text); text-decoration: underline; }
.kv-contactpage .kv-contactpage__said a:hover,
.kv-contactpage .kv-contactpage__value a:hover { color: var(--kv-primary); }

/* ---------------------------------------------------------------------------
   Blog archive, nodes 2:26685 (1440), 2:26739 (834) and 2:26791 (375)
   ------------------------------------------------------------------------ */

/* The masthead runs edge to edge and starts straight under the header, so the
   main element gives up the 1440 cap, the side gutter and the 100 top padding
   it carries everywhere else. Each section puts the gutter back, and the
   content inside them stays 1136 wide and centred however wide the screen is. */
.kv-blog { max-width: none; padding: 0; }

/* Masthead. Two illustrations, not one scaled: the wide one is cropped at 834,
   and the phone gets its own where the drummer carries the frame and the words
   sit top left instead of centred. */
.kv-bhero { position: relative; display: flex; justify-content: center; height: 442px; padding: 132px var(--kv-gutter) 0; }
.kv-bhero__art { position: absolute; inset: 0; display: block; }
.kv-bhero__art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.kv-bhero__words { position: relative; width: 745px; max-width: 100%; display: flex; flex-direction: column; gap: 24px; text-align: center; }
.kv-blog .kv-bhero__words h1 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-bhero__words p { margin: 0 auto; max-width: 505px; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }

/* Sections */
.kv-bsection { padding: 64px var(--kv-gutter) 0; }
.kv-bsection--all { padding-bottom: 64px; }
.kv-bsection__inner { max-width: 1136px; margin-inline: auto; }

/* The three featured cards */

/* The filter bar, node 2:26708 */
.kv-bbar {
	display: flex; align-items: flex-start; gap: 32px;
	padding-bottom: 24px; margin-bottom: 32px;
	border-bottom: 1px solid var(--kv-grey-600);
}
.kv-bchips { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 12px; }
/* The chips are links, so Elementor's kit colours them orange unless the theme
   states the colour at two classes deep. They stay in the text colour at rest
   and on hover; only the background moves. */
.kv-blog .kv-bchip {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 9px 11px; border: 1px solid transparent; border-radius: 8px;
	background: var(--kv-primary-8);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); text-decoration: none;
	white-space: nowrap; transition: background-color .15s;
}
.kv-blog .kv-bchip:hover { background: var(--kv-primary-16); color: var(--kv-text); }
.kv-blog .kv-bchip.is-on { border-color: var(--kv-text); }
.kv-bsort { flex: 0 0 auto; padding: 10px 0; }

/* The blog's own sort, node 1:3103. It is not the shop's: the panel is narrow,
   carries no border, and tints the current choice rather than marking it some
   other way. It hangs off the right on desktop, where the control sits at the
   right margin; once the control moves to the left margin the panel follows it,
   which is what the two variants in the component sheet show. Without that it
   opened at x -98, off the side of the screen. */
.kv-bsort .kv-filter__panel {
	left: auto; right: 0; top: calc(100% + 8px);
	min-width: 127px; width: max-content; padding: 0; gap: 0;
	border: 0; border-radius: 8px; overflow: hidden;
}
.kv-bsort .kv-filter__opt {
	display: flex; align-items: center; min-height: 40px;
	padding: 8px 16px; border-radius: 0;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
/* The chosen row is Grey/200, node 1:3108, the same grey the shop's sort
   list uses. It had been a step darker. */
.kv-bsort .kv-filter__opt.is-on { background: var(--kv-grey-200); }
.kv-bsort .kv-filter > summary .karivarah-icon { width: 24px; height: 24px; }

/* The grid, and the pagination under it */
/* grid-auto-rows: 1fr makes every row as tall as the tallest card in it, and
   the rows match each other, so a one-line title does not give a card a
   different height from its neighbours. */
.kv-bgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 1fr; column-gap: 28px; row-gap: 32px; }
.kv-bempty { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-blog .kv-pages { margin-top: 64px; }

/* A card, node I2:26720 */
.kv-bcard { display: flex; flex-direction: column; gap: 16px; height: 100%; }
.kv-bcard__pic { display: block; border-radius: 8px; overflow: hidden; }
.kv-bcard__img { display: block; width: 100%; height: 220px; object-fit: cover; }
/* The body takes the slack the picture does not, and the tags sit on its floor,
   so they line up across a row whatever the title and summary do above them. */
.kv-bcard__body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 12px; }
.kv-bcard__text { display: flex; flex-direction: column; gap: 8px; }
.kv-bcard__head { display: flex; flex-direction: column; gap: 4px; }
.kv-bcard__meta { margin: 0; font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); color: var(--kv-text-2); }
/* A heading, so the archive can be walked by its post titles, which means the
   kit's own heading size has to be overruled here. */
/* Node 1:3222: the title row is a fixed 48, two lines' worth, not just clamped
   to it. A one-line title keeps the row open so the summary and the tags start
   at the same height on every card in a row. */
.kv-site .kv-bcard__h { margin: 0; height: 48px; display: flex; align-items: flex-start; gap: 12px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); font-weight: var(--kv-weight-semibold); }
.kv-site .kv-bcard__h a {
	flex: 1 1 auto; min-width: 0;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text); text-decoration: none;
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.kv-bcard__arrow { flex: 0 0 auto; display: flex; padding-top: 4px; color: var(--kv-text); }
.kv-bcard__excerpt {
	margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2);
	display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.kv-bcard__tags { margin: auto 0 0; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; list-style: none; }
.kv-btag { padding: 4px 8px; border-radius: 4px; background: var(--kv-primary-8); font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text); }

/* Hovering anywhere on the card underlines the title and straightens the arrow.
   The title keeps its colour: this is the one place on the site where a link
   hover is not the orange, so it opts out of the global rule by name. */
.kv-site .kv-bcard:hover .kv-bcard__h a,
.kv-main .kv-bcard__h a:focus-visible { text-decoration: underline; }
.kv-site .kv-bcard__h a:hover,
.kv-main .kv-bcard__h a:focus-visible { color: inherit; }
.kv-bcard:hover .karivarah-icon--arrow-up-right,
.kv-bcard__h a:focus-visible ~ .kv-bcard__arrow .karivarah-icon--arrow-up-right { transform: rotate(45deg); }

/* The featured form of the same card: a tinted panel with the picture flush to
   the top, node I2:26701 */

/* 834 */
@media (max-width: 1024px) {
	/* The chips wrap to two and three rows at this width, which left the sort
	   floating at the top right with nothing beside it. It drops under them and
	   starts at the margin instead, the way the phone frame has it. */
	.kv-bbar { flex-direction: column; align-items: flex-start; gap: 16px; }
	.kv-bsort { padding: 0; }
	.kv-bsort .kv-filter__panel { left: 0; right: auto; }

	/* 40/48, not a smaller size with the desktop leading: measured off the frame,
	   the title holds its 40 and tightens the leading, breaking after "Universe". */
	.kv-bhero { height: 324px; padding-top: 54px; }
	.kv-blog .kv-bhero__words h1 { font-size: 40px; line-height: 48px; }
	/* The frame sets the title over two lines here, widest line 425, so the
	   block is held near that rather than running the full 674. */
	.kv-bhero__words { width: 430px; }
	.kv-bhero__words p { max-width: 465px; }
	.kv-bhero__words p { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); max-width: 465px; }

	.kv-bgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 20px; }
}

/* 375 */
@media (max-width: 767px) {
	.kv-bhero { padding-top: 18px; justify-content: flex-start; }
	.kv-blog .kv-bhero__words h1 { font-size: 28px; line-height: 40px; }
	/* The illustration puts its subject on the right, and measured off the file
	   at phone width she starts at x300 across the title's band and x233 across
	   the paragraph's. The two therefore get different widths: the title may run
	   to 300, the paragraph stops at 215, and neither crosses her. */
	.kv-bhero__words { width: auto; max-width: none; text-align: left; gap: 16px; }
	.kv-blog .kv-bhero__words h1 { max-width: min(296px, 100%); }
	.kv-bhero__words p { margin-inline: 0; max-width: min(215px, 58vw); }

	.kv-bsection { padding-top: 36px; }
	/* The chips run off the edge and scroll, and the sort drops below them. */
	.kv-bbar { padding-bottom: 20px; margin-bottom: 24px; }
	.kv-bchips {
		width: 100%; flex-wrap: nowrap; gap: 10px;
		overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
		margin-right: calc(-1 * var(--kv-gutter)); padding-right: var(--kv-gutter);
	}
	.kv-bchips::-webkit-scrollbar { display: none; }
	.kv-blog .kv-bchip { padding: 7px 11px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-bsort { padding: 0; }
	.kv-bsort .kv-filter > summary { height: auto; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-bsort .kv-filter > summary .karivarah-icon { width: 20px; height: 20px; }
	.kv-bsort .kv-filter__opt { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-bgrid { grid-template-columns: minmax(0, 1fr); row-gap: 24px; }
	.kv-blog .kv-pages { margin-top: 32px; }
}

/* ---------------------------------------------------------------------------
   Blog post, nodes 2:22739 (1440), 2:25359 (834) and 2:24010 (375)
   ------------------------------------------------------------------------ */

.kv-postpage { max-width: none; padding: 0; }

/* How far down the article the reader has come, node 2:22743.
   Sticky, in the flow under the header where the frame draws it: visible at
   rest, pinned to the top once the page moves, let go over the footer. A
   `fixed` version was tried and dropped, because at rest it sat over the
   header and had to be hidden. The bar is an open bug on the client's own
   machine; the developer notes have the record. */
.kv-progress {
	position: sticky; top: 0; z-index: 60;
	height: 4px; background: var(--kv-grey-900);
}
.kv-progress__bar { display: block; height: 100%; width: 0; background: var(--kv-primary); }

/* The masthead: words on the left, picture filling the right half, node 2:22745 */
/* Node 2:22745. The whole section carries the primary at 8%, with the soft grey
   lines over it on the words' side; the picture covers the right half. */
/* The shared banner carries the geometry. What differs is its height, the
   100px of air above the trail, and that its words are spaced by their own
   margins rather than by the banner's gap. */
.kv-phero {
	--kv-banner-h: 560px;
	--kv-banner-pad-y: 100px;
	--kv-banner-gap: 0;
	background: var(--kv-primary-8);
}
/* The trail shares the title's column, wraps to a second line when it needs one,
   and truncates a single crumb that is longer than the line rather than running
   past the heading. */
.kv-phero .kv-crumbs { max-width: 100%; flex-wrap: wrap; row-gap: 4px; }
.kv-phero .kv-crumbs > * { min-width: 0; }
.kv-phero .kv-crumbs a,
.kv-phero .kv-crumbs [aria-current] { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.kv-postpage .kv-phero__h { margin: 16px 0 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text); }
.kv-phero__stand { margin: 24px 0 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2); }
.kv-phero__by { margin-top: 32px; display: flex; align-items: center; gap: 16px; }
/* No mask, as on the About page: the illustrated avatars are round already
   and the hair and shoulders break the circle on purpose, which a radius
   shears off. The letters badge below puts its own circle back, being a drawn
   badge rather than a picture. */
.kv-phero__avatar { width: 56px; height: 56px; flex: 0 0 56px; }
.kv-phero__who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kv-phero__name { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-phero__meta { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
/* The picture is taken out of the row's sizing: left in, a square image makes
   the masthead as tall as it is wide. The column keeps the frame's 560 and the
   words decide anything beyond that. */
.kv-phero__pic { position: relative; overflow: hidden; }
.kv-phero__img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }

/* The article and its sidebar, node 2:22766 */
.kv-post { padding: 100px var(--kv-gutter); }
/* The frame's 752 and 320 are what 1136 of content makes; written as a fixed
   pair they stood 1136 wide whatever the window was and pushed the page
   sideways everywhere below 1440. The article column gives way instead, and
   below 1180 there is not enough left for both, so the page reads as it does
   on a tablet: one column, with the contents in the dropdown. */
.kv-post__inner { max-width: 1136px; margin-inline: auto; display: grid; grid-template-columns: minmax(0, 1fr) 320px; column-gap: 64px; align-items: start; }
.kv-post__body { grid-column: 1; min-width: 0; }
/* Nothing in this column follows the reader down. The contents did, which is a
   kindness over a handful of sections and a nuisance over a long one, and the
   newsletter never did: a card chasing the reader down the page is an advert. */
.kv-post__side { grid-column: 2; align-self: start; display: flex; flex-direction: column; }
/* Node 2:22871 does not space these evenly: 40 under the newsletter card, 32
   under the share row. One `gap` flattened both to the larger number and left
   too much air under the card. Written as margins between siblings rather than
   a gap, so a legal document, whose contents are the only thing in the column,
   still starts level with its first line. */
.kv-post__side > * + * { margin-top: 40px; }
.kv-post__side > * + .kv-toc { margin-top: 32px; }
.kv-post__share { display: none; }

/* The written part. Blocks are spaced by one rhythm, and the rules between
   sections come from the frame rather than from the editor. */
.kv-post__text > * { margin-block: 0 32px; }
.kv-post__text > *:last-child { margin-bottom: 0; }
/* The first block starts level with the contents beside it. A heading carries
   48px above it to part it from the section before, and there is no section
   before the first one. The template class is in the selector to outweigh the
   heading rules below, which carry one of their own. */
.kv-postpage .kv-post__text > *:first-child { margin-top: 0; }
.kv-postpage .kv-post__text h2 { margin-top: 48px; font-weight: var(--kv-weight-semibold); font-size: 32px; line-height: 40px; color: var(--kv-text); scroll-margin-top: 120px; }
.kv-postpage .kv-post__text h3 { margin-top: 32px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text); }
/* The next rung down the system's ladder, SemiBold/H6 on the type sheet, node
   1:582. Nothing on the blog has needed it; the legal documents do. */
.kv-postpage .kv-post__text h4 { margin-top: 32px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-post__text p, .kv-post__text li { font-size: 16px; line-height: 28px; color: var(--kv-text); }

/* ---------------------------------------------------------------------------
   The dropdown a writer can put in an article, node 1:2879

   WordPress's own Details block, dressed as the frame draws it: a line of
   prose with a caret beside it, and the longer passage underneath in the
   secondary colour once it is opened. The writer adds it from the editor
   like any other block, so nothing here needs a shortcode.

   The caret is Phosphor's, as a background on the summary, because a mark
   cannot be inlined from CSS and this is the shape the rest of the site's
   disclosures use.
   ------------------------------------------------------------------------ */
.kv-post__text .wp-block-details {
	display: flex; flex-direction: column; gap: 12px;
}
.kv-post__text .wp-block-details > summary {
	display: flex; align-items: flex-start; gap: 12px;
	list-style: none; cursor: pointer;
	font-size: 16px; line-height: 28px; color: var(--kv-text);
}
.kv-post__text .wp-block-details > summary::-webkit-details-marker { display: none; }
.kv-post__text .wp-block-details > summary::after {
	content: ""; flex: 0 0 24px; width: 24px; height: 24px; margin-top: 2px;
	background: center / 24px no-repeat
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23231F20'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E");
	transition: transform .15s;
}
.kv-post__text .wp-block-details[open] > summary::after { transform: rotate(180deg); }
/* What opens is the quieter half, and it carries no margins of its own: the
   block's gap does the spacing. */
.kv-post__text .wp-block-details > :not(summary) { margin: 0; color: var(--kv-text-2); }
.kv-post__text .wp-block-details > :not(summary) + :not(summary) { margin-top: 12px; }
/* A paragraph nested deeper than the first level takes the same quiet
   colour; the rule above only reaches the block's own children. */
.kv-post__text .wp-block-details > :not(summary) p { color: inherit; }
/* Prose links only. A blanket rule here reaches into the product cards in the
   rail and the related posts, and paints their names orange and underlined. */
.kv-post__text p a,
.kv-post__text li a,
.kv-post__text blockquote a,
.kv-post__text figcaption a { color: var(--kv-primary); text-decoration: underline; }
.kv-post__text img { border-radius: 8px; }
/* The media slot in the article is a band, node 2:22838 at 752 by 402, not
   whatever shape the file happens to be: a square upload was filling 752 by 752
   and swamping the column. A wide or square picture fills the band and crops to
   it. A portrait one keeps its own shape, since cropping a tall picture to a
   band throws away the reason it was tall. */
.kv-post__text .wp-block-image img,
.kv-post__text .wp-block-video video {
	width: 100%; height: auto;
	aspect-ratio: 752 / 402; object-fit: cover;
}
.kv-post__text .wp-block-image.kv-img--tall img {
	aspect-ratio: auto; object-fit: contain;
	width: auto; max-width: 100%; height: auto; margin-inline: auto;
}
.kv-post__text .wp-block-image.kv-img--tall { display: flex; flex-direction: column; align-items: center; }
.kv-post__text .wp-block-image.kv-img--tall figcaption { align-self: stretch; }
.kv-post__text figure { margin: 0 0 32px; }
.kv-post__text figcaption { margin-top: 8px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-post__text blockquote {
	margin: 0 0 32px; padding: 24px 32px; border-left: 2px solid var(--kv-primary);
	background: var(--kv-primary-4); border-radius: 0 12px 12px 0;
}
.kv-post__text hr { height: 1px; margin: 48px 0; border: 0; background: var(--kv-grey-600); }

/* Contents, node 2:22903. Orange on hover, which is the one place a link in
   this column changes colour. */
.kv-toc__h { margin: 0 0 16px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-toc__list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 16px; }
.kv-postpage .kv-toc__list a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); text-decoration: none; }
.kv-postpage .kv-toc__list a:hover,
.kv-postpage .kv-toc__list a:focus-visible { color: var(--kv-primary); }
.kv-toc--drop { display: none; }
/* Node 1:3160. Not a boxed control: a rule above and below the whole thing,
   the label in semibold with the caret right after it, and the list inside the
   same rules when it opens. The component has two sizes, 20 padding with 16/24
   type at tablet and 16 padding with 14/20 on the phone, and the list runs at
   gap 10 in the primary text colour, not the secondary. */
.kv-toc--drop {
	padding: 20px 0;
	border-top: 1px solid var(--kv-grey-400);
	border-bottom: 1px solid var(--kv-grey-400);
}
.kv-toc--drop > summary {
	display: flex; align-items: center; gap: 12px;
	padding: 0; border: 0; border-radius: 0;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
	cursor: pointer; list-style: none;
}
.kv-toc--drop > summary::-webkit-details-marker { display: none; }
.kv-toc--drop > summary .karivarah-icon { width: 24px; height: 24px; flex: 0 0 24px; transition: transform .15s; }
.kv-toc--drop[open] > summary .karivarah-icon { transform: rotate(180deg); }
.kv-toc--drop .kv-toc__list { padding: 12px 0 0; gap: 10px; }
.kv-postpage .kv-toc--drop .kv-toc__list a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }

/* The newsletter card in the sidebar, node 2:22872 */
.kv-sidenews { padding: 24px; border-radius: 12px; background: var(--kv-primary-4); }
.kv-sidenews__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
.kv-sidenews__text { margin: 12px 0 20px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-sidenews .kv-signup { flex-direction: column; gap: 12px; }
.kv-sidenews .kv-signup .kv-field { flex: 0 0 auto; width: 100%; }
.kv-sidenews .kv-signup .kv-field .kv-field__input { color: var(--kv-text); }
.kv-sidenews .kv-signup__button { width: 100%; }
.kv-sidenews .kv-foot__consent { margin-top: 16px; }

/* Shop the story, node 2:22841 */
.kv-story { margin: 48px 0; }
.kv-story__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.kv-postpage .kv-story__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: 32px; line-height: 40px; color: var(--kv-text); }
.kv-story__lead { margin: 16px 0 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-story__rail {
	margin-top: 32px; display: flex; gap: 24px;
	overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; scrollbar-width: none;
}
.kv-story__rail::-webkit-scrollbar { display: none; }
.kv-story__rail > * { flex: 0 0 214px; scroll-snap-align: start; }

/* The call to action, node 2:22863 */
.kv-cta {
	position: relative; margin-top: 48px; padding: 32px;
	display: flex; align-items: center; gap: 32px;
	border-radius: 16px; background: var(--kv-primary-8); overflow: hidden;
}
.kv-cta__words { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 24px; }
.kv-postpage .kv-cta__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text); }
/* The heading and the sentence sit 16 apart inside the 24 the button takes. */
.kv-cta__h + .kv-cta__text { margin-top: -8px; }
.kv-cta__text { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
/* The frame uses the medium button here, not the site's large one, the same
   way the FAQ card does. */
.kv-postpage .kv-cta .kv-btn { padding: 12px 20px; border-radius: 12px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-cta__pic { flex: 0 0 240px; }
.kv-cta__pic img { display: block; width: 240px; height: 240px; object-fit: cover; border-radius: 12px; }

/* Read similar blogs, node 2:22910 */
.kv-similar { position: relative; padding: 100px var(--kv-gutter); }
.kv-similar__inner { max-width: 1136px; margin-inline: auto; }
.kv-postpage .kv-similar__h { margin: 0 0 64px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }

/* 834: the sidebar breaks up. The contents become a dropdown above the article,
   the share row drops under it, and the newsletter is left to the footer. */
@media (max-width: 1179px) {
	.kv-post__inner { grid-template-columns: minmax(0, 1fr); }
	.kv-post__side { display: none; }
	.kv-post__share { display: block; margin-top: 48px; }
	.kv-toc--drop { display: block; margin-bottom: 32px; }
}

@media (max-width: 1024px) {
	.kv-postpage .kv-phero__h { font-size: 32px; line-height: 40px; }

	.kv-post { padding: 64px var(--kv-gutter); }
	.kv-post__inner { grid-template-columns: minmax(0, 1fr); }
	.kv-post__side { display: none; }
	.kv-post__share { display: block; margin-top: 48px; }
	.kv-toc--drop { display: block; margin-bottom: 32px; }

	.kv-postpage .kv-post__text h2 { font-size: 28px; line-height: 36px; }
	.kv-postpage .kv-story__h { font-size: 28px; line-height: 36px; }

	.kv-similar { padding: 64px var(--kv-gutter); }
	.kv-postpage .kv-similar__h { margin-bottom: 48px; font-size: 32px; line-height: 40px; }

	/* Node 2:25515: three cards do not fit 674 here, and the frame scrolls them
	   rather than dropping one. The phone stacks them instead, below. */
	.kv-similar .kv-bgrid {
		display: flex; align-items: stretch; gap: 20px;
		overflow-x: auto; overflow-y: hidden;
		scroll-snap-type: x mandatory; scrollbar-width: none;
		margin-right: calc(-1 * var(--kv-gutter)); padding-right: var(--kv-gutter);
	}
	.kv-similar .kv-bgrid::-webkit-scrollbar { display: none; }
	/* A fixed card width only keeps the next card in view at one exact viewport.
	   At 768 the third card began 6px past the edge and the rail looked like it
	   ended. The width is derived from the rail instead, so two cards and a 48px
	   slice of the third fit at every tablet width. */
	.kv-similar .kv-bgrid > .kv-bcard { flex: 0 0 calc((100% - 88px) / 2); height: auto; scroll-snap-align: start; }
}

/* 375 */
@media (max-width: 767px) {
	.kv-phero { --kv-banner-pad-y: 36px; }
	.kv-postpage .kv-phero__h { font-size: 28px; line-height: 36px; }
	.kv-phero__by { margin-top: 32px; gap: 12px; }
	.kv-phero__avatar { width: 48px; height: 48px; flex-basis: 48px; }

	.kv-post { padding: 36px var(--kv-gutter); }
	/* The component's small size: 16 padding, 14/20 throughout, 20px caret. */
	/* The small dropdown in an article, node 1:2893, closes the gap to 8. The
	   type stays the article's own 16/28 at every width, because the block
	   sits in that prose and the frame sets the article's measure, not this
	   component's. */
	.kv-post__text .wp-block-details { gap: 8px; }
	.kv-post__text .wp-block-details > :not(summary) + :not(summary) { margin-top: 8px; }
	.kv-toc--drop { padding: 16px 0; }
	.kv-toc--drop > summary { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-toc--drop > summary .karivarah-icon { width: 20px; height: 20px; flex-basis: 20px; }
	.kv-postpage .kv-toc--drop .kv-toc__list a { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-postpage .kv-post__text h2 { margin-top: 36px; font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-post__text > * { margin-bottom: 24px; }

	/* A table squeezed into 343 becomes unreadable, so it keeps a working width
	   and scrolls inside its figure instead. */
	.kv-post__text .wp-block-table { overflow-x: auto; }
	.kv-post__text .wp-block-table table { min-width: 480px; }

	.kv-story__head { align-items: flex-start; }
	.kv-postpage .kv-story__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-story__rail > * { flex-basis: 180px; }

	/* 375, node 2:24129: the words centre, the button fills the width and the
	   picture drops underneath at 295 square. */
	.kv-cta { flex-direction: column; align-items: stretch; gap: 32px; padding: 24px; border-radius: 12px; }
	.kv-cta__words { align-items: center; text-align: center; gap: 24px; }
	.kv-postpage .kv-cta__h { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-cta__text { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-postpage .kv-cta__words .kv-btn { width: 100%; border-radius: 10px; padding: 12px 16px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	/* The frame's 295 is the full width inside the card's 24 padding at 375, not
	   a fixed size: the picture squares off the column the button already fills,
	   so the two stay the same width on any phone. */
	.kv-cta__pic { flex: 0 0 auto; width: 100%; }
	.kv-cta__pic img { width: 100%; height: auto; aspect-ratio: 1; border-radius: 8px; }

	.kv-similar { padding: 36px var(--kv-gutter); }
	.kv-postpage .kv-similar__h { margin-bottom: 24px; font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }

	/* The phone stacks them, nodes 2:24163 to 2:24165. */
	.kv-similar .kv-bgrid {
		display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px;
		overflow: visible; margin-right: 0; padding-right: 0;
	}
	.kv-similar .kv-bgrid > .kv-bcard { flex: none; height: 100%; }
}

/* A writer with no picture uploaded gets their initials rather than a request
   to Gravatar and a stranger's silhouette. */
.kv-phero__avatar--letters {
	display: grid; place-items: center; border-radius: 100px;
	background: var(--kv-primary-12); color: var(--kv-primary);
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-sub1); line-height: 1;
}
.kv-sidenews__consent { margin: 16px 0 0; font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); color: var(--kv-text-2); }
.kv-sidenews__consent a { color: var(--kv-text-2); text-decoration: underline; }

/* --- Blog post: corrections against the frame ---------------------------- */

/* The table, node 2:22774. The theme's own table already carries the right
   colours; what the editor's figure loses is the rounded wrapper and the pale
   fill behind the body, and a first column marked as a heading has to look
   like one. */
.kv-post__text .wp-block-table {
	border-radius: 8px; overflow: auto; background: var(--kv-grey-100);
}
/* WordPress's block stylesheet gives every cell a grey border and collapses the
   table, which draws a hairline across the top that the frame does not have and
   makes the theme's own dividers unreliable. Rather than fight it rule by rule,
   the post table states its borders outright: nothing on a cell, then the
   dividers put back where the frame has them. */
.kv-post__text .wp-block-table table { margin: 0; border-collapse: separate; border-spacing: 0; }
.kv-post__text .wp-block-table th,
.kv-post__text .wp-block-table td { border: 0; padding: 12px 20px; }
.kv-post__text .wp-block-table tbody tr + tr th,
.kv-post__text .wp-block-table tbody tr + tr td { border-top: 1px solid var(--kv-grey-500); }
.kv-post__text .wp-block-table tbody th + td,
.kv-post__text .wp-block-table tbody td + td { border-left: 1px solid var(--kv-grey-500); }
.kv-post__text .wp-block-table thead th + th { border-left: 1px solid var(--kv-paper); }
/* One more line to kill, and it hides behind a logical property: a reset rule
   puts `border-block-start` on the first row of every table, which a plain
   `border: 0` does not touch and which outranks it anyway. This is the grey
   hairline that ran across the top of the heading row. */
.kv-post__text .wp-block-table thead:first-child tr:first-child th,
.kv-post__text .wp-block-table thead:first-child tr:first-child td { border-block-start: 0; }

.kv-post__text .is-style-kv-head-col tbody tr > th,
.kv-post__text .is-style-kv-head-both tbody tr > th {
	background-color: var(--kv-grey-400) !important; color: var(--kv-text);
}
/* Inside a heading column the dividers go white, the same as the heading row. */
.kv-post__text .is-style-kv-head-col tbody th + td,
.kv-post__text .is-style-kv-head-both tbody th + td,
.kv-post__text .is-style-kv-head-col tbody tr + tr th,
.kv-post__text .is-style-kv-head-both tbody tr + tr th { border-left-color: var(--kv-paper); border-top-color: var(--kv-paper); }

/* The rail's own arrows are filled circles at 48, node 2:22844, not the bare
   32 the other carousels use. */
.kv-story .kv-arrows { gap: 20px; }
.kv-story .kv-arrow,
.kv-story .kv-arrow:hover,
.kv-story .kv-arrow:focus {
	width: 48px; height: 48px; flex: 0 0 48px;
	background: var(--kv-grey-300) !important;
}
.kv-story .kv-arrow:hover { background: var(--kv-grey-500) !important; color: var(--kv-text) !important; }
.kv-story .kv-arrow[disabled] { color: var(--kv-text-disabled) !important; }

/* ---------------------------------------------------------------------------
   404, node 3:120511 (1440, 834 and 375)
   ------------------------------------------------------------------------ */

.kv-404 { max-width: none; padding: 0; }

/* Words left, picture filling the right half, the band on the primary at 8%,
   node 3:120516. The same construction as the blog post masthead. */
/* The shared banner again. A taller band, a taller picture once it stacks, and
   its own margins between the words. */
.kv-404__band {
	--kv-banner-h: 620px;
	--kv-banner-h-md: 360px;
	--kv-banner-pad-y: 64px;
	--kv-banner-gap: 0;
	background: var(--kv-primary-8);
}

/* The button sits to its own width rather than filling the column, which is
   the only thing these words need beyond the banner's own rules. */
.kv-404__words { align-items: flex-start; }
.kv-404__eyebrow { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-primary); }
.kv-404 .kv-404__h {
	margin: 16px 0 0;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1);
	color: var(--kv-text);
}
.kv-404__text { margin: 24px 0 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2); }
.kv-404__words .kv-btn { margin-top: 32px; }

/* The picture is taken out of the row's sizing, as the post masthead's is: left
   in, a wide illustration would set the band's height rather than fill it. */
.kv-404__pic { position: relative; overflow: hidden; }
.kv-404__pic .kv-picture,
.kv-404__pic img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }

/* 834: the picture goes on top, node 3:120534 */
/* Node 2:120571 holds the words to 513 once the halves stack. */
@media (max-width: 1179px) {
	.kv-404__words { width: 513px; max-width: 100%; }
}

@media (max-width: 767px) {
	.kv-404__words { width: auto; }
}

@media (max-width: 1024px) {
	.kv-404 .kv-404__h { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
}

/* 375, node 3:120551 */
@media (max-width: 767px) {
	.kv-404__band { --kv-banner-pad-y: 48px; }
	/* The shared banner opens a 16 gap between its words on a phone; here the
	   margins below carry the frame's 8, 16 and 24, node 3:120554. */
	.kv-404__words { gap: 0; }
	.kv-404__eyebrow { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-404 .kv-404__h { margin-top: 8px; font-size: 28px; line-height: 40px; }
	.kv-404__text { margin-top: 16px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	.kv-404__words .kv-btn { margin-top: 24px; }
}

/* ---------------------------------------------------------------------------
   Legal documents, template-legal.php

   The top is the category page's header, nodes 2:23254 (1440), 2:24929 (834)
   and 2:23576 (375). Below it the page is a blog post: it carries that
   template's class, so the body rhythm, the heading ladder, the contents list
   and the reading bar are the ones already written rather than a second set
   that could drift. What is left here is the band the header sits in.
   ------------------------------------------------------------------------ */

/* The header card at x=152, y=100, 1136 wide, which is the gutter and the
   content column the rest of the site uses. */
.kv-legal__head { padding: 100px var(--kv-gutter) 0; }
.kv-legal__head .kv-termhead { max-width: 1136px; margin-inline: auto; }

/* The whole page carries the primary at 8%, the same wash as the post masthead
   and the error page. */
.kv-legalpage { background: var(--kv-primary-8); }

/* The document holds no picture, so the subheading keeps the frame's measure
   rather than running the width of the screen. */
.kv-legalpage .kv-termhead__desc { max-width: 596px; }

/* A file to take away under the note, spaced by the header's own gap: the
   angreskjema on the returns page (karivarah_legal_downloads()). */
.kv-legal__downloads { margin: 0; }

/* The download link, node 2:22720 on the About page's press band: a 20 icon
   and Body 1 in the primary, 6 apart, no underline. The frame draws no hover;
   it darkens to the primary's pressed shade, as the primary does. The site
   class outweighs the kit's link colour. */
.kv-site .kv-dlink {
	display: inline-flex; align-items: center; gap: 6px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-primary); text-decoration: none;
}
.kv-site .kv-dlink:hover { color: var(--kv-primary-dark); }
.kv-dlink__icon { flex: 0 0 20px; width: 20px; height: 20px; }

/* 834, node 2:24929 */
@media (max-width: 1024px) {
	.kv-legal__head { padding-top: 64px; }
}

/* 375, node 2:23576: the header's own size, 30/40, which is SemiBold/H4 on the
   type sheet at node 1:580. */
@media (max-width: 767px) {
	.kv-legal__head { padding-top: 36px; }
	.kv-legalpage .kv-termhead .kv-termhead__title { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }

	/* The phone drops H2 to 24/32, which is what H3 already is, so two levels
	   land on the same size. An article rarely notices; a document with eleven
	   subsections under nineteen sections loses its shape. The two below it
	   step down the system's ladder instead: SemiBold/H6 at node 1:582 and
	   SemiBold/Subheading 1 at node 1:583. */
	.kv-legalpage .kv-post__text h3 { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-legalpage .kv-post__text h4 { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
}

/* ---------------------------------------------------------------------------
   Complianz's privacy and cookie policies, in the house style

   Complianz prints its documents inside `#cmplz-document` and styles them
   from its own sheet: 14px text, 22px headings, grey bars and white tables.
   Its rules carry the id, so they outrank the article's. Each rule here
   carries the page, the article and the id, and restates the
   article's values from the same tokens: the type ladder and rhythm of the
   legal documents above, the article dropdown (node 1:2879) for the
   expandable sections, and the house table (node 2:25394) for the cookie
   lists. Complianz's sheet stays loaded, because it also hides the consent
   controls until their script runs and hides its own spare inputs. Matched
   15.10.2026 against the Terms and Conditions at 1440, 834 and 375.
   ------------------------------------------------------------------------ */

.kv-legalpage .kv-post__text #cmplz-document {
	max-width: none; margin: 0;
	font-size: 16px; line-height: 28px; color: var(--kv-text);
}

/* The article's rhythm: one 32px step between blocks, more above a heading. */
.kv-legalpage .kv-post__text #cmplz-document > *,
.kv-legalpage .kv-post__text #cmplz-document #cmplz-cookies-overview > * { margin: 0 0 32px; }
.kv-legalpage .kv-post__text #cmplz-document > :first-child { margin-top: 0; }
.kv-legalpage .kv-post__text #cmplz-document > :last-child,
.kv-legalpage .kv-post__text #cmplz-document #cmplz-cookies-overview > :last-child { margin-bottom: 0; }
.kv-legalpage .kv-post__text #cmplz-document h2,
.kv-legalpage .kv-post__text #cmplz-document h3,
.kv-legalpage .kv-post__text #cmplz-document h4,
.kv-legalpage .kv-post__text #cmplz-document h5 {
	padding: 0; border: 0; text-transform: none; text-align: left;
	font-weight: var(--kv-weight-semibold); color: var(--kv-text);
}
.kv-legalpage .kv-post__text #cmplz-document > h2 { margin-top: 48px; font-size: 32px; line-height: 40px; scroll-margin-top: 120px; }
.kv-legalpage .kv-post__text #cmplz-document > h3 { margin-top: 32px; font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
.kv-legalpage .kv-post__text #cmplz-document p,
.kv-legalpage .kv-post__text #cmplz-document li { margin-top: 0; font-size: 16px; line-height: 28px; color: var(--kv-text); }
.kv-legalpage .kv-post__text #cmplz-document ul { margin-left: 0; padding-left: 40px; list-style: disc; }

/* Links as in the article. Complianz pins a black arrow picture after every
   link that opens a new tab and draws a black box on focus; the site has
   neither, and keeps its own focus ring. */
.kv-legalpage .kv-post__text #cmplz-document a { color: var(--kv-primary); text-decoration: underline; font-size: inherit; }
.kv-legalpage .kv-post__text #cmplz-document a[target=_blank]::after { content: none; }
.kv-legalpage .kv-post__text #cmplz-document a:focus { border: 0; padding: 0; }

/* --- The expandable sections, as the article dropdown -------------------- */

.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown {
	display: flex; flex-direction: column; gap: 12px;
	padding: 0; background: none;
}
/* A run of them sits closer than the article's blocks, as a list does. The
   privacy policy puts loose text between its heading and the first one, which
   no margin can reach, so the first one keeps its distance from the heading. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown + .cmplz-dropdown { margin-top: -16px; }
.kv-legalpage .kv-post__text #cmplz-document > h2 + .cmplz-dropdown { margin-top: 32px; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary { margin: 0; padding: 0; background: none; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary > div { display: flex; align-items: flex-start; gap: 12px; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary h3 {
	flex: 1 1 auto; min-width: 0; margin: 0; padding: 0;
	font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6);
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary:hover h3 { color: var(--kv-primary); }
/* Phosphor's caret, as on the article dropdown, in place of Complianz's chevron. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary > div::after {
	content: ""; flex: 0 0 24px; width: 24px; height: 24px; margin: 2px 0 0;
	background: center / 24px no-repeat
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23231F20'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E");
	transition: transform .15s;
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown[open] summary > div::after { transform: rotate(180deg); }
/* What opens is the quieter half, spaced by the dropdown's gap. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown > :not(summary) { margin: 0; padding: 0; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown p,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown li { margin: 0; padding: 0; color: var(--kv-text-2); }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown ul { margin: 0; padding: 0 0 0 24px; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown p:empty { display: none; }
/* The labels inside, "Retention period", "Usage", "Sharing data": the
   article's body size, semibold, with their text straight under them. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown > h3,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown h4 { margin: 0; padding: 0; font-size: 16px; line-height: 28px; }
/* The privacy policy's sections are flat: label, text, label, text. Each
   label sits on its text and a step above the one before. */
.kv-legalpage .kv-post__text #cmplz-document .dropdown-privacy-statement { gap: 0; }
.kv-legalpage .kv-post__text #cmplz-document .dropdown-privacy-statement > summary { margin-bottom: 12px; }
.kv-legalpage .kv-post__text #cmplz-document .dropdown-privacy-statement > p + h3 { margin-top: 12px; }

/* A cookie service: its name, its category in the quieter colour, the caret. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown-cookiepolicy summary p {
	flex: 0 0 auto; margin: 0; padding: 0;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-h6); color: var(--kv-text-2);
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown-cookiepolicy summary label,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown-cookiepolicy summary input { flex: 0 0 0; margin: 0; }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cmplz-service-description,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cmplz-sharing-data { display: block; width: auto; padding: 0; }

/* --- The cookie lists, as the house table --------------------------------
   Complianz draws the table as a grid of divs on a coloured ground, the 1px
   gaps showing through as the lines. The ground takes the house divider and
   the cells the table's pale fill; the heading cells take the heading grey
   and paint the dividers beside them white, as the heading row does. */
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose {
	margin: 0; border: 0; border-radius: 12px; overflow: hidden;
	background: var(--kv-grey-500);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose div {
	padding: 12px; background-color: var(--kv-grey-100);
	color: var(--kv-text-2); overflow-wrap: anywhere;
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .purpose,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .name-header,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .retention-header,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .function-header {
	background-color: var(--kv-grey-400); color: var(--kv-text);
}
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .purpose { box-shadow: 0 1px 0 var(--kv-paper); }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose h4,
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose h5 { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose h5 { font-weight: var(--kv-weight); }
.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose a { color: inherit; }
@media (min-width: 601px) {
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .name-header,
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .retention-header { box-shadow: 1px 0 0 var(--kv-paper), 0 1px 0 var(--kv-grey-400); }
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose .function-header { box-shadow: 0 1px 0 var(--kv-grey-400); }
}

/* The consent controls under 7.1 are the banner's categories, drawn by
   Complianz's script, and take the consent banner's styling further down. */

/* 834: the article's H2 steps down. */
@media (max-width: 1024px) {
	.kv-legalpage .kv-post__text #cmplz-document > h2 { font-size: 28px; line-height: 36px; }
}

/* 375: the legal documents' phone ladder and the article's tighter rhythm.
   Below 600 Complianz gives each cookie a label column, which is the house's
   label and value table, so that layout is kept and coloured as one. */
@media (max-width: 767px) {
	.kv-legalpage .kv-post__text #cmplz-document > *,
	.kv-legalpage .kv-post__text #cmplz-document #cmplz-cookies-overview > * { margin-bottom: 24px; }
	.kv-legalpage .kv-post__text #cmplz-document > :last-child,
	.kv-legalpage .kv-post__text #cmplz-document #cmplz-cookies-overview > :last-child { margin-bottom: 0; }
	.kv-legalpage .kv-post__text #cmplz-document > h2 { margin-top: 36px; font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-legalpage .kv-post__text #cmplz-document > h3 { font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); }
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown { gap: 8px; }
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown + .cmplz-dropdown { margin-top: -8px; }
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown summary h3 { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
	.kv-legalpage .kv-post__text #cmplz-document .dropdown-privacy-statement > summary { margin-bottom: 8px; }
	.kv-legalpage .kv-post__text #cmplz-document .dropdown-privacy-statement > p + h3 { margin-top: 8px; }
	.kv-legalpage .kv-post__text #cmplz-document > h2 + .cmplz-dropdown { margin-top: 24px; }
	.kv-legalpage .kv-post__text #cmplz-document .cmplz-dropdown .cookies-per-purpose div { padding: 10px 12px; }
}

/* ---------------------------------------------------------------------------
   About us, nodes 2:22592 (1440), 2:25215 (834) and 2:23858 (375)

   The page is one column of bands. Every band carries the gutter and its own
   vertical rhythm, which steps 100 / 64 / 36 with the frames, and the headings
   step H2 / H3 / H5 while the body steps Body 1 / Body 1 / Body 2.

   Two column bands stack at 1179 rather than at 1024. The frames only draw
   1440 and 834, and between those widths a 536px picture beside a column of
   prose leaves the prose too narrow to read, which is the same reason the shop
   panel gives up at that width.
   ------------------------------------------------------------------------ */

/* The content column, 1136, the same as every other page on the site.
   `--kv-gutter` is set so that 1440 less two gutters is exactly 1136, so below
   1440 the gutter is the measurement the frames draw and above it the column
   holds at 1136 and centres, which is what `.kv-main` and the trust and
   sitemap bands do. The band itself stays full width, so a tint still runs to
   both edges of the screen. */
.kv-about__section {
	position: relative;
	padding-block: 100px;
	padding-inline: max(var(--kv-gutter), calc((100% - 1136px) / 2));
	overflow: hidden;
}

.kv-about__tint { background: var(--kv-primary-4); }

.kv-about__section > *:not(.kv-veins) { position: relative; z-index: 1; }

/* Placeholders. The design draws most pictures as a grey box naming what goes
   in it, and these print the same thing. The grey is the design's own
   placeholder colour rather than a palette value, and it leaves with them. */
.kv-ph {
	--kv-ph-grey: #C4C4C4;
	display: flex; align-items: center; justify-content: center;
	background: var(--kv-ph-grey); border-radius: 8px;
	overflow: hidden; text-align: center; padding: 16px;
}
.kv-ph__label {
	color: var(--kv-text-2);
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
}

/* Shared pieces of a band */
.kv-about__words { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
/* Two classes deep: Elementor's kit sets `h1` and `h2` with a class and an
   element, which beats a bare class however late it comes. Without this the
   headings kept their 1440 size at every width. */
.kv-about .kv-about__h {
	margin: 0;
	font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2);
	color: var(--kv-text);
}
.kv-about__h--centre { text-align: center; }
.kv-about__body { display: flex; flex-direction: column; gap: 24px; }
.kv-about__body p {
	margin: 0;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	color: var(--kv-text-2);
}
.kv-about__cta { align-self: flex-start; margin-top: 12px; }

/* Hero, node 2:22596. The shared banner over an 8% primary wash. Its height is
   the token's default, so nothing here restates 480. */
.kv-about__hero { background: var(--kv-primary-8); }
/* Stacked, this hero stands its words 88 clear of the picture and the foot,
   node 2:25219, where the shared banner gives 48. */
@media (min-width: 768px) and (max-width: 1179px) {
	.kv-about__hero .kv-banner__words { padding-top: 88px; padding-bottom: 88px; }
}
.kv-about .kv-about__hero-title {
	margin: 0;
	font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1);
	color: var(--kv-text);
}
.kv-about__hero-lead {
	margin: 0;
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1);
	color: var(--kv-text-2);
}

/* The story, node 2:22604 */
.kv-about__story { display: flex; flex-direction: column; gap: 64px; }
.kv-about__row {
	display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center;
}
.kv-about__row--flip .kv-about__story-media { order: 2; }
.kv-about__story-media { height: 402px; border-radius: 12px; }

/* A collection built on craft, node 2:22619 */
.kv-about__collection {
	display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center;
}
.kv-about__grid4 {
	display: grid; grid-template-columns: 1fr 1fr; gap: 24px;
}
.kv-about__grid4 .kv-about__tile { height: 256px; border-radius: 8px; }

/* Handcrafted, node 2:22634 */
.kv-about__craft { display: flex; flex-direction: column; gap: 64px; }
.kv-about__grid4--row { grid-template-columns: repeat(4, 1fr); }
.kv-about__grid4--row .kv-about__tile { height: 266px; }

/* By the numbers, node 2:22641 */
.kv-about__numbers { display: flex; flex-direction: column; gap: 48px; align-items: center; }
.kv-about__stats {
	display: flex; gap: 120px; justify-content: center;
	margin: 0; padding: 0; list-style: none;
}
.kv-about__stat { display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.kv-about__figure {
	font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1);
	color: var(--kv-primary);
}
.kv-about__statlabel {
	font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6);
	color: var(--kv-text);
}

/* From our home to yours, node 2:22655. The frame gives the words 552 and the
   map 536, not half each, so the map is held at the size it is drawn. */
.kv-about__map {
	display: grid; grid-template-columns: 1fr 536px; gap: 48px; align-items: center;
}
.kv-about__mapslot { aspect-ratio: 1 / 1; border-radius: 8px; }

/* The map itself, drawn by MapGeo into a canvas-like SVG. Only the card is
   ours: amCharts paints everything else, so its colours live in inc/map.php
   where the plugin can be handed them, not here. */
.kv-about__mapslot.kv-map { border-radius: 0; }
.kv-map .map_wrapper { margin: 0; }
.kv-map .map_box { max-width: none; }

/* The card a country shows on hover, node 2:22670. It sits inside the
   plugin's tooltip, whose own box is made invisible in the script beside it,
   so the card draws its own ground, corner and shadow. */
.kv-map__card {
	display: block; width: 160px; overflow: hidden;
	border-radius: 4px; background: var(--kv-paper);
	box-shadow: var(--kv-elevation-5);
}
.kv-map__shot {
	display: block; position: relative; height: 120px;
	background-size: cover; background-position: center;
}
.kv-map__shot::after { content: ''; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.4); }
/* `a.` and the card in front of it, because the site's own `.kv-site a`
   reset is more specific than a bare class and would hand the button the
   ink colour it inherits from the tooltip. */
.kv-map__card a.kv-map__cta {
	position: absolute; z-index: 1;
	left: 50%; top: 50%; transform: translate(-50%, -50%);
	padding: 8px 12px; border-radius: 12px; white-space: nowrap;
	background: var(--kv-primary); color: var(--kv-white);
	font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption);
	text-decoration: none;
}
.kv-map__name {
	display: block; padding: 8px; text-align: center;
	color: var(--kv-text);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}

/* Stay connected, node 2:22671 */
.kv-about__social {
	display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center;
}
.kv-about__socialmedia { height: 536px; border-radius: 12px; }
.kv-about__channels { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 12px; }
.kv-about__channel { flex: 0 0 auto; }
.kv-about__channelicon { width: 24px; height: 24px; flex: 0 0 auto; }
.kv-about__channelicon path { fill: currentColor; }

/* This is us, node 2:22684 */
.kv-about__people { display: flex; flex-direction: column; gap: 64px; }
.kv-about__teamlist {
	display: flex; gap: 48px; justify-content: center; flex-wrap: wrap;
	margin: 0; padding: 0; list-style: none;
}
.kv-about__member { display: flex; flex-direction: column; align-items: center; width: 300px; }
.kv-about__membermedia { width: 100%; height: 280px; border-radius: 8px; }

/* The page's photographs, which were grey boxes until 13.10.2026. Each slot
   already carries its own height and corner from the frames, so all the
   pictures need is to fill it and let the box do the cropping. The clipping
   used to come from `.kv-ph`, which these boxes no longer wear. */
.kv-about__heromedia,
.kv-about__story-media,
.kv-about__tile,
.kv-about__socialmedia,
.kv-about__membermedia { overflow: hidden; }
.kv-about__heromedia .kv-picture,
.kv-about__story-media .kv-picture,
.kv-about__tile .kv-picture,
.kv-about__socialmedia .kv-picture,
.kv-about__membermedia .kv-picture { display: block; width: 100%; height: 100%; }
.kv-about__heromedia img,
.kv-about__story-media img,
.kv-about__tile img,
.kv-about__socialmedia img,
.kv-about__membermedia img { width: 100%; height: 100%; object-fit: cover; }
.kv-about__memberbody {
	display: flex; flex-direction: column; align-items: center; gap: 8px;
	margin-top: -80px; text-align: center;
}
/* No mask. The frame draws a 160 square and the roundness in it belongs to
   the artwork, so a photograph that is not round keeps its corners rather
   than losing them. */
.kv-about__avatar {
	width: 160px; height: 160px; display: block;
	margin-bottom: 8px;
}
.kv-about__membername { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text); }
.kv-about__memberrole { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }

/* ---------------------------------------------------------------------------
   About at 1179 and below: the two column bands stack, picture first, which is
   how both smaller frames draw them.
   ------------------------------------------------------------------------ */

@media (max-width: 1179px) {
	.kv-about__row,
	.kv-about__collection,
	.kv-about__map,
	.kv-about__social { grid-template-columns: 1fr; gap: 48px; }

	.kv-about__row--flip .kv-about__story-media { order: 0; }

	/* The collection and the map put their words first and the pictures under
	   them, nodes 2:25240 and 2:25279. The story and Stay connected put the
	   picture first, nodes 2:25225 and 2:25286. */
	.kv-about__collection .kv-about__grid4 { order: 2; }
	.kv-about__map .kv-about__mapslot { order: 2; width: 100%; max-width: 536px; margin: 0 auto; }

	.kv-about__story-media,
	.kv-about__socialmedia { height: 400px; }

	.kv-about__grid4 .kv-about__tile { height: 325px; }
	.kv-about__grid4--row { grid-template-columns: 1fr 1fr; }
	.kv-about__grid4--row .kv-about__tile { height: 325px; }

	.kv-about__stats { gap: 24px; justify-content: space-between; width: 100%; }

	.kv-about__teamlist { gap: 28px; flex-wrap: nowrap; }
	.kv-about__member { width: auto; flex: 1 1 0; min-width: 0; }
	.kv-about__membermedia { height: 182px; }
	.kv-about__memberbody { margin-top: -50px; }
	.kv-about__avatar { width: 100px; height: 100px; }

}

/* 1024 and below: the frame's own type and rhythm, node set 2:25215 */
@media (max-width: 1024px) {
	.kv-about__section { padding-block: 64px; }
	.kv-about .kv-about__hero-title { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
	.kv-about .kv-about__h { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	.kv-about__story { gap: 48px; }
	.kv-about__craft,
	.kv-about__people { gap: 48px; }
	.kv-about__statlabel { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); }
}

/* 767 and below, node set 2:23858 */
@media (max-width: 767px) {
	.kv-about__section { padding-block: 36px; }
	.kv-about .kv-about__hero-title { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
	.kv-about .kv-about__hero-lead { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }

	.kv-about .kv-about__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-about__words { gap: 16px; }
	.kv-about__body { gap: 16px; }
	.kv-about__body p,
	.kv-ph__label { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-about__story,
	.kv-about__craft,
	.kv-about__people { gap: 24px; }
	.kv-about__row,
	.kv-about__collection,
	.kv-about__map,
	.kv-about__social { gap: 24px; }

	.kv-about__story-media,
	.kv-about__socialmedia { height: 240px; border-radius: 8px; }

	.kv-about__grid4 { gap: 15px; }
	.kv-about__grid4 .kv-about__tile,
	.kv-about__grid4--row .kv-about__tile { height: 164px; border-radius: 4px; }

	/* The numbers stack into one centred column, node 2:23908 */
	.kv-about__numbers { gap: 36px; }
	.kv-about__stats { flex-direction: column; gap: 16px; width: 205px; }
	.kv-about__stat { gap: 4px; }
	.kv-about__figure { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	.kv-about__statlabel { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }

	/* Three on a row becomes a wrapping row of 164 wide cards, node 2:23953 */
	.kv-about__teamlist { gap: 15px; flex-wrap: wrap; justify-content: flex-start; }
	.kv-about__member { width: 164px; flex: 0 0 auto; }
	.kv-about__membermedia { height: 138px; }
	.kv-about__memberbody { gap: 4px; }
	.kv-about__membername { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
	.kv-about__memberrole { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

	.kv-about__channels { gap: 16px; }
	.kv-about__channelicon { width: 20px; height: 20px; }

	/* Three rows of two, node 2:23993 */

}

/* The buttons step down with the frames: the medium size below 1024 and on a
   phone, nodes 2:23888 and 2:23991. */
@media (max-width: 767px) {
	.kv-about .kv-btn--secondary { border-width: var(--kv-btn-stroke-md); }
}

/* A social button with no URL behind it yet. It is drawn exactly as the frame
   draws it and simply does not react, because the design has no greyed state
   and inventing one would be a second answer to a question nobody asked. */
.kv-about__channel--waiting { cursor: default; }

/* ---------------------------------------------------------------------------
   The gallery, nodes 2:131195 (1440), 2:131049 (834) and 2:130976 (375),
   with the image view at 2:131142, 2:131169 and 2:130954.

   The frames draw a mosaic of fixed tiles: two squares here, a wide one there,
   a tall one down the side. That only holds while every picture is the shape
   the designer had. This is a masonry instead, so a portrait, a square and a
   panorama can be uploaded in any order and each keeps its own proportions.
   The columns are equal and the gaps are the frame's: 24, and 15 on a phone.
   ------------------------------------------------------------------------ */

.kv-gal { max-width: 1440px; margin: 0 auto; padding: 100px var(--kv-gutter); }
.kv-gal > * { max-width: 1136px; margin-inline: auto; }
.kv-gal .kv-termhead { margin-bottom: 48px; }
.kv-gal__empty { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }

/* The masonry.
   `column-count` balances its columns by height, which is the wrong rule for
   pictures: it picks one height for all three, fills each column up to it and
   tips everything that will not fit into the last one. A page carrying a few
   tall strips ends with two short columns, a long one, and a hole at the foot
   of the first two.
   So the columns are packed instead, each picture going to whichever column is
   currently shortest. That needs measuring, which needs script, so the rules
   below are the no-script layout and `.is-packed` is what the script swaps to.
   The two custom properties are read by the script, which is how the
   breakpoints stay here in the CSS rather than being written twice. */
.kv-gal__grid { --kv-gal-cols: 3; --kv-gal-gap: 24px; column-count: var(--kv-gal-cols); column-gap: var(--kv-gal-gap); }
.kv-gal__tile { break-inside: avoid; margin: 0 0 24px; }

.kv-gal__grid.is-packed { position: relative; column-count: auto; }
.kv-gal__grid.is-packed .kv-gal__tile { position: absolute; top: 0; left: 0; margin: 0; }

.kv-gal__open {
	display: block; width: 100%; position: relative;
	padding: 0 !important; border: 0 !important; background: none !important;
	border-radius: 8px; overflow: hidden; cursor: pointer;
}
.kv-gal__img { display: block; width: 100%; height: auto; border-radius: 8px; }

/* The caption rides over the foot of the picture, node 2:131213: a wash over
   the whole tile and a fade under the words. It is only drawn where something
   has been written, and only while the tile is being looked at. */
.kv-gal__cap {
	position: absolute; inset: 0; border-radius: 8px;
	display: flex; flex-direction: column; justify-content: flex-end;
	padding: 8px; gap: 0;
	background:
		linear-gradient(90deg, rgba(0, 0, 0, .3) 0%, rgba(0, 0, 0, .3) 100%),
		linear-gradient(180deg, rgba(0, 0, 0, 0) 71.894%, rgba(0, 0, 0, .56) 89.571%);
	opacity: 0; transition: opacity .2s; text-align: left;
}
.kv-gal__open:hover .kv-gal__cap,
.kv-gal__open:focus-visible .kv-gal__cap { opacity: 1; }
.kv-gal__meta {
	display: flex; flex-wrap: wrap; gap: 0 4px;
	color: var(--kv-grey-900);
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
}
.kv-gal__title {
	color: var(--kv-paper);
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
	overflow: hidden; text-overflow: ellipsis;
}

.kv-gal .kv-pages { margin-top: 48px; }

/* ---------------------------------------------------------------------------
   The image view's own panel. The shell around it is `.kv-lightbox`.
   ------------------------------------------------------------------------ */

.kv-gal__view {
	--kv-gal-stage: 436px;
	--kv-gal-thumb: 100px;
	--kv-gal-pad: 20px;
	--kv-gal-card: 600px;
}

/* The card is the size the frame draws it and stays that size, node 2:131143
   at 600 square. Every word under the picture is optional, so a card sized to
   its contents would shrink on a picture with no credit and jump about as the
   reader stepped through. The picture's row is fixed by the stage, and the
   words take whatever is left, filled from the top. */
.kv-gal__panel {
	width: min(calc(var(--kv-gal-stage) + 24px + var(--kv-gal-thumb) + var(--kv-gal-pad) * 2), calc(100vw - 32px));
	height: var(--kv-gal-card);
	max-height: calc(100dvh - 48px);
	padding: var(--kv-gal-pad);
	border-radius: 12px; background: var(--kv-paper);
	display: flex;
}

/* The card does not scroll: the close and the two round buttons sit outside it
   on purpose, and a scrolling card clips them. Anything too tall for the
   screen scrolls inside the card instead. */
.kv-gal__body {
	flex: 1 1 auto; min-height: 0;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	grid-template-rows: auto minmax(0, 1fr);
	gap: 24px;
	overflow: auto; scrollbar-width: none;
}
.kv-gal__body::-webkit-scrollbar { width: 0; height: 0; }

/* A square stage, and the picture sits inside it whole. The frames draw square
   pictures; a gallery that takes any shape cannot crop to that, so nothing is
   cropped and the stage holds whatever is left over. */
.kv-gal__stage {
	grid-column: 1; position: relative;
	aspect-ratio: 1 / 1; border-radius: 12px; overflow: hidden;
	background: var(--kv-grey-200);
}
.kv-gal__slide { position: absolute; inset: 0; }
.kv-gal__slide img,
.kv-gal__full { width: 100%; height: 100%; object-fit: contain; display: block; }

.kv-gal__rail {
	grid-column: 2; grid-row: 1;
	list-style: none; margin: 0; padding: 0;
	display: flex; flex-direction: column; justify-content: flex-start; gap: 12px;
	max-height: var(--kv-gal-stage); overflow: hidden;
}
.kv-gal__rail::-webkit-scrollbar { width: 0; height: 0; }
.kv-gal .kv-gal__thumb,
.kv-gal__thumb {
	display: block; width: var(--kv-gal-thumb); height: var(--kv-gal-thumb);
	padding: 0 !important; border: 2px solid transparent !important; border-radius: 8px;
	background: none !important; overflow: hidden; cursor: pointer;
}
/* No ring on a thumbnail: the rail shows what is coming rather than where the
   reader is, so none of them is the current picture. The dim at rest is the
   magnifier's own pattern for a rail like this, and it is the affordance the
   frame leaves out. */
.kv-gal__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: .75; }
.kv-gal__thumb:hover img,
.kv-gal__thumb:focus-visible img { opacity: 1; }

/* Stretched to its row rather than sized to its text: a short caption leaves
   the space below it empty and a long one scrolls inside, so neither changes
   the height of the card. The words themselves start at the top. */
.kv-gal__words { grid-column: 1 / -1; grid-row: 2; min-height: 0; overflow: auto; scrollbar-width: none; }
.kv-gal__words::-webkit-scrollbar { width: 0; height: 0; }
.kv-gal__about { display: flex; flex-direction: column; gap: 16px; }
.kv-gal__line { display: flex; gap: 24px; align-items: flex-start; }
.kv-gal__names { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; color: var(--kv-text); }
.kv-gal__name { font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); overflow: hidden; text-overflow: ellipsis; }
.kv-gal__credit { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
.kv-gal__out {
	flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
	color: var(--kv-text); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}
.kv-gal__out .karivarah-icon { width: 24px; height: 24px; }
.kv-gal__where {
	margin: 0; display: flex; flex-wrap: wrap; gap: 8px;
	color: var(--kv-text-2);
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
}

@media (max-width: 1179px) {
	.kv-gal__grid { --kv-gal-cols: 2; }
}

@media (max-width: 1024px) {
	.kv-gal { padding: 64px var(--kv-gutter); }
	.kv-gal .kv-termhead { margin-bottom: 36px; }
	.kv-gal__view { --kv-gal-stage: 324px; --kv-gal-card: 493px; }
	.kv-gal__name { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
}

/* On a phone the rail goes under the picture, node 2:130954 */
@media (max-width: 767px) {
	.kv-gal { padding: 36px var(--kv-gutter); }
	.kv-gal__grid { --kv-gal-gap: 15px; }
	.kv-gal__tile { margin-bottom: 15px; }
	.kv-gal__open, .kv-gal__img, .kv-gal__cap { border-radius: 4px; }
	.kv-gal .kv-pages { margin-top: 24px; }

	.kv-gal__view { --kv-gal-stage: 280px; --kv-gal-thumb: 64px; --kv-gal-pad: 16px; --kv-gal-card: 532px; }
	.kv-gal__panel { width: min(calc(var(--kv-gal-stage) + var(--kv-gal-pad) * 2), calc(100vw - 32px)); }
	.kv-gal__body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr); gap: 8px; }
	.kv-gal__stage { border-radius: 8px; }
	.kv-gal__rail {
		grid-column: 1; grid-row: auto;
		flex-direction: row; justify-content: flex-start; gap: 8px;
		max-height: none; overflow-x: auto;
	}
	.kv-gal__thumb { border-radius: 4px; }
	.kv-gal__words { grid-row: 3; margin-top: 16px; }
	.kv-gal__name { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-gal__credit, .kv-gal__where { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
	.kv-gal__out { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-gal__out .karivarah-icon { width: 20px; height: 20px; }
	.kv-gal__line { flex-direction: column; gap: 16px; }

	/* Node 2:130954 draws neither arrow nor close over the picture, and the
	   rail does the stepping, so the arrows go.

	   The close comes back, 14.10.2026, at the client's request: it had been
	   hidden here from 09.10.2026, leaving a press outside as the only way
	   out of a full-screen picture, which is not a gesture a phone offers and
	   nothing on the screen said. It sits above the picture on the overlay
	   rather than inset at its corner, which is what the client asked for and
	   what keeps it off a photograph it would otherwise sit on. */
	.kv-gal__view .kv-lightbox__nav { display: none; }
	.kv-gal__view .kv-lightbox__close,
	.kv-gal__view .kv-lightbox__close:focus {
		/* Fixed to the screen rather than hung off the panel: the panel grows
		   to within 24 of the top on a short one, and a cross hung above it
		   would go with it.

		   Right rather than centred, 14.10.2026, and lined up with the card
		   below it rather than with the screen: this card is narrower than
		   the gutter, 312 against 343 at 375, so the two are not the same
		   edge. The calc is the card's own width expression, halved for the
		   gutter either side, less the 4 the icon sits inside its press. */
		position: fixed; top: 12px; left: auto; bottom: auto;
		right: calc(max((100vw - (var(--kv-gal-stage) + var(--kv-gal-pad) * 2)) / 2, 16px) - 4px);
		transform: none;
		width: 40px; height: 40px; margin: 0; overflow: visible;
		clip-path: none;
		padding: 4px !important;
		background: none !important; color: var(--kv-paper) !important;
	}
}

/* The bar over the grid, holding the sort. The control is the shop's and the
   blog's; only where it sits is the gallery's own. */
.kv-gal__bar { display: flex; justify-content: flex-end; margin-bottom: 24px; }
@media (max-width: 767px) { .kv-gal__bar { margin-bottom: 16px; } }

/* ---------------------------------------------------------------------------
   The home page, nodes 2:22392 (1440), 2:24238 (834) and 2:23342 (375)

   Twelve bands, eight of them components the other pages already carry. What
   is written here is the four that had nowhere else to live, plus the places
   where a shared component is arranged differently on this page than on the
   one it was built for.

   Two things to know before changing anything here.

   The page is a shortcode in an Elementor canvas, so it is **not** inside
   `.kv-main`. Any component rule scoped to `.kv-main` is simply absent on this
   page, which is how the blog card came to be drawn at heading size here and
   at its own size everywhere else.

   The Elementor kit styles `h1` to `h6` as `.elementor-kit-6 h2`, which weighs
   0,1,1 and beats a bare class. Every rule below that sets type or colour on a
   heading element is prefixed with `.kv-site`, the body class, for the same
   reason the type ladder is.
   ------------------------------------------------------------------------ */

.kv-home { display: flex; flex-direction: column; }
.kv-home > * { width: 100%; }

/* The shell. Every band that holds words stands in the same column the rest of
   the site uses: 1440 wide with a 152 gutter, which leaves the 1136 the frames
   measure. `.kv-prow` and `.kv-reviews` already say this for themselves. The
   three that run edge to edge, the hero, the promo band and the trust row, are
   left alone. */
.kv-home .kv-cards,
.kv-home .kv-hfaq,
.kv-home .kv-habout,
.kv-hub .kv-hblogs,
.kv-hub .kv-hgal {
	max-width: 1440px; margin-inline: auto;
	padding: 100px var(--kv-gutter);
}
.kv-home .kv-reviews { max-width: 1440px; margin-inline: auto; }

.kv-home .kv-hfaq > *,
.kv-hub .kv-hblogs > *,
.kv-hub .kv-hgal > * { max-width: 1136px; margin-inline: auto; }

/* A tinted band runs edge to edge on every page, the way the trust row and the
   sitemap do; only its content keeps the 1136 column (15.10.2026). These two
   carried the tint inside the 1440 shell, so on a wider screen it stopped
   short, and their drawing stopped shorter still, at the column. */
.kv-home .kv-hfaq,
.kv-hub .kv-hblogs { max-width: none; }
.kv-home .kv-hfaq > .kv-veins,
.kv-hub .kv-hblogs > .kv-veins { max-width: none; margin: 0; }

/* Every band carries its own 100 top and bottom, so one band's end is the next
   band's beginning. The trust row is the only one that asked for a margin, for
   the pages where it follows something that does not. */
.kv-home .kv-trust { margin-top: 0; }

/* ---------------------------------------------------------------------------
   The content hub, nodes 121:130834, 121:134073 and 121:137270, 11.10.2026
   -------------------------------------------------------------------------*/

.kv-hub { display: flex; flex-direction: column; }
.kv-hub > * { width: 100%; }

/* The same banner the About page opens with, at the homepage hero's height and
   on the 8 per cent wash the frame draws. The words run to the newsletter
   field, so the measure is the banner's own rather than the hero's 425. */
.kv-hub__hero {
	--kv-banner-h: 620px; --kv-banner-h-md: 360px; --kv-banner-h-sm: 240px;
	background: var(--kv-primary-8);
}
.kv-hub__h { margin: 0; }
.kv-hub__lead { margin: 0; max-width: 425px; }

/* The sign-up sits in the band rather than the footer's dark strip, so it
   takes the band's measure and the field grows into it. */
.kv-hub__hero .kv-signup { max-width: 425px; }
.kv-hub__consent {
	margin: 0; max-width: 425px;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2);
}

/* The second band is tinted where the first is white, node 121:130944. */
/* The illustration fills its half, and the figure is centred in both crops,
   so cover takes the excess off the sides rather than off the subject. */
.kv-hub__media { display: block; }
.kv-hub__media img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }

.kv-hub .kv-hblogs { background: var(--kv-primary-4); }

/* The hero, node 2:22396. The banner, standing taller than it does anywhere
   else and on the 8 per cent wash, which is the one band on the page that is
   not white or the 4 per cent tint. */

.kv-hero {
	--kv-banner-h: 620px; --kv-banner-h-md: 360px; --kv-banner-h-sm: 240px;
	background: var(--kv-primary-8);
}
/* The measure is 425, node 2:22397, narrower than the 504 the banner holds
   elsewhere: the heading takes three lines here and wants to. */
.kv-hero__words > * { max-width: 425px; }
.kv-site .kv-hero__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h1); line-height: var(--kv-lh-h1); color: var(--kv-text); }
.kv-hero__lead { margin: 0; font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text-2); }
/* 24 from the banner's own column gap and 12 here makes the frame's 36. */
.kv-hero__cta { margin: 12px 0 0; }
/* The photograph fills the slot and the browser does the cropping: the
   banner is 720 by 620 beside the words and a band the width of the page once
   it stacks, and a flat lay survives both. */
.kv-hero__pic .kv-picture { display: block; width: 100%; height: 100%; }
.kv-hero__pic img { width: 100%; height: 100%; object-fit: cover; }

/* The new arrivals band, node 2:22438.
   The only place on the site where type sits over a photograph, so the scrim
   belongs to the band and not to the picture: a photograph swapped in later
   cannot take the contrast away with it. */

.kv-promo { position: relative; display: grid; min-height: 420px; }
.kv-promo > * { grid-area: 1 / 1; }
.kv-promo__pic { overflow: hidden; }
/* The picture is taken out of the flow so it fills the band rather than
   setting its height: left in it, a 3:2 photograph makes a 1440 band 960 tall
   and the design's 420 goes with it. Weighted low, because a centred crop of
   this one lands on the tiled wall and loses the woven stools under it. */
.kv-promo__pic { position: relative; }
.kv-promo__pic .kv-picture,
.kv-promo__pic img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.kv-promo__pic img { object-fit: cover; object-position: center 72%; }
.kv-promo::after {
	content: ""; grid-area: 1 / 1; z-index: 1;
	background: linear-gradient(180deg, rgba(35, 31, 32, .55) 0%, rgba(35, 31, 32, .55) 100%);
}
.kv-promo__words {
	position: relative; z-index: 2;
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	gap: 36px; padding: 64px var(--kv-gutter); text-align: center;
}
.kv-site .kv-promo__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-white); }
.kv-promo__lead { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-white); }
/* 36 from the column gap and 12 here makes the 48 under the lead. */
.kv-promo__cta { margin: 12px 0 0; }

/* The questions band, node 2:22457. Four questions open on a desktop, two
   columns 48 apart and 32 between the rows. */

.kv-hfaq { position: relative; background: var(--kv-primary-4); }
.kv-hfaq__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 64px; }
.kv-site .kv-hfaq__head h2 { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-hfaq__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px 48px; }
/* The question is Regular, not SemiBold: it is the mark beside it that carries
   the weight, node 2:22472. */
.kv-site .kv-hfaq__q {
	display: flex; align-items: center; gap: 12px; margin: 0 0 20px;
	font-weight: var(--kv-weight); font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text);
	list-style: none; cursor: default;
}
.kv-hfaq__q::-webkit-details-marker { display: none; }
.kv-hfaq__q > span { flex: 1 1 auto; min-width: 0; }
.kv-hfaq__q .karivarah-icon { width: 32px; height: 32px; flex: 0 0 32px; color: var(--kv-primary); }
/* Node 2:22464 draws no caret: the answers are already open at this width. */
.kv-hfaq__caret { display: none; }
.kv-hfaq__a { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-hfaq__a p { margin: 0 0 8px; }
.kv-hfaq__a p:last-child { margin-bottom: 0; }

/* The band about the shop, node 2:22517. Two pictures set off against each
   other, the second overlapping the first and standing lower. Both are
   portrait, 260 by 360 inside a 544 by 456 box, so they are written as
   proportions of that box rather than as four fixed numbers. */

.kv-habout { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: 64px; }
.kv-habout__words { display: flex; flex-direction: column; gap: 24px; }
.kv-site .kv-habout__h { margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-habout__words p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-habout__cta { margin-top: 12px; }
/* One picture where the frame draws two overlapping cards, and sized the way
   the About page sizes the one picture in its Stay connected band: a height
   that steps with the breakpoints rather than a ratio, so the two bands are
   the same component on two pages. 536 beside the words, 400 once it stacks,
   240 on a phone. */
.kv-habout__media { height: 536px; border-radius: 12px; overflow: hidden; }
.kv-habout__media .kv-picture { display: block; width: 100%; height: 100%; }
.kv-habout__media img { width: 100%; height: 100%; object-fit: cover; }

/* The blog band, node 2:22528, and the gallery band, node 2:22539. The same
   head: a heading with a line under it one side, a button the other. */

.kv-hblogs { position: relative; background: var(--kv-primary-4); }
.kv-hblogs__head,
.kv-hgal__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 64px; }
.kv-site .kv-hblogs__head h2,
.kv-site .kv-hgal__head h2 { margin: 0 0 24px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); color: var(--kv-text); }
.kv-hblogs__head p,
.kv-hgal__head p { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-hblogs__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }

/* The mosaic, node 2:22546. Four columns of 266 and two rows of it: a square,
   a wide one over two columns, a tall one down two rows, then three squares.
   The order in the markup is the order they are placed, so nothing here names
   a picture; the shapes come from where a tile falls. */

.kv-hgal__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.kv-hgal__grid > .kv-gal__tile { margin: 0; aspect-ratio: 1; }
.kv-hgal__grid > .kv-gal__tile:nth-child(2) { grid-column: span 2; aspect-ratio: 556 / 266; }
.kv-hgal__grid > .kv-gal__tile:nth-child(3) { grid-row: span 2; aspect-ratio: 266 / 556; }
.kv-hgal__grid > .kv-gal__tile > .kv-gal__open { height: 100%; }
.kv-hgal__grid .kv-gal__img { width: 100%; height: 100%; object-fit: cover; }

/* The reviews band's call to action, node 2:22456, centred under the dots. */
/* The carousel block stands 384 in the frame, node 2:22455: the cards, 24,
   the dots, and 24 of its own below them. The button then sits 64 under the
   block, so from the dots it is 88. Margins between siblings collapse, which
   is why the space is carried here rather than under the dots. */
.kv-reviews__cta { margin: 88px 0 0; display: flex; justify-content: center; }

/* The product rails, nodes 2:22405 and 2:22444. Everything about them is the
   row the product page already draws, and the one thing the home page changes
   is that a button stands in the head, node 2:22406, where the product page
   has only the heading. The arrows are in the gutter on both. */
.kv-prow--home .kv-prow__head { align-items: center; }

@media (max-width: 1024px) {
	/* Node 2:24238. The gutter is 80 and the bands are 64 deep.

	   Alignment changes here, and not everywhere the same way. Every band
	   centres its head and moves its call to action from beside the heading to
	   under the band, nodes 2:24253, 2:24340, 2:24359, 2:24375, 2:24394 and
	   2:24404. The two exceptions are the browse-card bands, which keep their
	   heading at the left with the arrows at the right, node 2:24299, and the
	   hero, which keeps its words at the left. */
	.kv-home .kv-cards,
	.kv-home .kv-hfaq,
	.kv-home .kv-habout,
	.kv-hub .kv-hblogs,
	.kv-hub .kv-hgal { padding: 64px var(--kv-gutter); }

	/* No floating arrows from here down. An 80 gutter cannot hold a 48 arrow
	   standing 88 outside the rail, and the frames draw none beside a product
	   row, node 2:24265, or the reviews. The arrows that stay are the ones
	   beside a browse-card heading, and they are 24 here, node 2:24303. */
	.kv-prow__rail > .kv-arrows { display: none; }
	/* Site-wide, not the home page's alone: every .kv-arrow at 1024 and below.
	   The arrows' own section points back here. */
	.kv-arrow,
	.kv-arrow:hover,
	.kv-arrow:focus { width: 24px; height: 24px; flex: 0 0 24px; }
	.kv-arrow .karivarah-icon { width: 20px; height: 20px; }

	/* The hero, node 2:24244: the picture is 360, the words start 72 under it,
	   the heading is H2 and the measure is 513. */
	.kv-hero { --kv-banner-pad-y: 72px; }
	.kv-hero__words > * { max-width: 513px; }
	.kv-site .kv-hero__h { font-size: var(--kv-fs-h2); line-height: var(--kv-lh-h2); }
	.kv-hero__cta { margin-top: 12px; }

	/* The head is a row on a desktop and a stack here, so each band becomes a
	   column and its head gives up its box: `display: contents` leaves the
	   heading and the button as children of the band, free to be ordered. */
	.kv-prow--home,
	.kv-home .kv-hfaq,
	.kv-hub .kv-hblogs,
	.kv-hub .kv-hgal { display: flex; flex-direction: column; }

	.kv-prow--home > .kv-prow__head,
	.kv-hfaq__head,
	.kv-hblogs__head,
	.kv-hgal__head { display: contents; }

	.kv-prow--home > .kv-prow__head > h2,
	.kv-site .kv-hfaq__head > h2,
	.kv-hblogs__head > div,
	.kv-hgal__head > div { order: 1; margin: 0 0 48px; text-align: center; }

	.kv-prow--home > .kv-prow__rail,
	.kv-hfaq__grid,
	.kv-hblogs__grid,
	.kv-hgal__grid { order: 2; }

	.kv-prow--home > .kv-prow__head > .kv-btn,
	.kv-hfaq__head > .kv-btn,
	.kv-hblogs__head > .kv-btn,
	.kv-hgal__head > .kv-btn { order: 3; margin: 48px auto 0; }

	.kv-site .kv-hblogs__head h2,
	.kv-site .kv-hgal__head h2 { margin: 0 0 24px; }

	/* A flex item with an automatic side margin does not stretch, and the cap
	   the bands carry for a wide screen sets one. Below 1025 nothing is as wide
	   as the cap anyway, so the grids take the column instead of shrinking to
	   their contents and centring. */
	.kv-hfaq__grid,
	.kv-hblogs__grid,
	.kv-hgal__grid { width: 100%; margin-inline: 0; }

	/* Node 2:24376: one column of folded rows, the caret at the end, and the
	   button goes to the page that answers them. The folding is the script in
	   inc/home.php; this is only how it looks. */
	.kv-hfaq__grid { grid-template-columns: 1fr; gap: 28px; }
	.kv-site .kv-hfaq__q { margin: 0; cursor: pointer; }
	.kv-hfaq__q .kv-hfaq__caret { display: block; flex: 0 0 24px; width: 24px; height: 24px; color: var(--kv-text); transition: transform .2s; }
	.kv-hfaq__item[open] .kv-hfaq__caret { transform: rotate(180deg); }
	.kv-hfaq__item[open] .kv-hfaq__a { margin-top: 20px; }

	/* Node 2:24397: the blog cards become a rail, cut by the edge of the
	   screen the way every other rail on the page is. */
	.kv-hblogs__grid {
		display: grid; grid-auto-flow: column;
		grid-template-columns: none; grid-auto-columns: 327px; gap: 20px;
		margin-left: 0; margin-right: calc(-1 * var(--kv-gutter));
		padding-right: var(--kv-gutter);
		overflow-x: auto; overflow-y: hidden;
		scroll-snap-type: x mandatory; scrollbar-width: none;
	}
	.kv-hblogs__grid::-webkit-scrollbar { width: 0; height: 0; }
	.kv-hblogs__grid > .kv-bcard { scroll-snap-align: start; }

	/* Node 2:24406: three columns, two squares and a wide one one side, a tall
	   one the other, and the last two pictures are not drawn. */
	/* The 834 frame draws a square, a square, a column down the right and a
	   band under the two squares, where the desktop order is square, band,
	   column, square. The tiles change places rather than changing shape, so
	   the picture chosen for the band is still in a band: it drops to the
	   second row and the fourth tile takes the seat it leaves. */
	.kv-hgal__grid { grid-template-columns: repeat(3, 1fr); gap: 16px; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(1) { grid-column: 1; grid-row: 1; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(2) { grid-column: 1 / span 2; grid-row: 2; aspect-ratio: 444 / 214; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(3) { grid-column: 3; grid-row: 1 / span 2; aspect-ratio: 214 / 444; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(4) { grid-column: 2; grid-row: 1; aspect-ratio: 1; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(n + 5) { display: none; }

	/* Node 2:24385: one picture across the column, above the words. The two
	   set off against each other is a desktop arrangement and there is no room
	   for it here, so the second one is not drawn. The words stay at the left
	   and only the button centres, node 2:24390. */
	.kv-habout { grid-template-columns: 1fr; gap: 48px; }
	.kv-habout__words { order: 2; }
	.kv-habout__media { order: 1; height: 400px; }
	.kv-habout__cta { display: flex; justify-content: center; }

	/* The tablet band, node 2:24314: 316 tall on a 64 pad, the heading at H3,
	   24 to the line under it and 36 to the button. */
	.kv-promo { min-height: 316px; }
	.kv-site .kv-promo__h { font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); }
	.kv-promo__words { gap: 24px; }
	.kv-promo__cta { margin: 12px 0 0; }
}

@media (max-width: 767px) {
	/* Node 2:23342. The gutter is 16, the bands are 36 deep, the headings drop
	   to H5 and the buttons to the medium size.

	   Alignment goes the other way from the tablet. Everything returns to the
	   left, nodes 2:23372, 2:23421, 2:23432, 2:23438 and 2:23446, and only the
	   three carousels keep a centred heading and a centred button, nodes
	   2:23356, 2:23389 and 2:23406. */
	.kv-home .kv-cards,
	.kv-home .kv-hfaq,
	.kv-home .kv-habout,
	.kv-home .kv-reviews,
	.kv-home .kv-prow,
	.kv-hub .kv-hblogs,
	.kv-hub .kv-hgal { padding: 36px var(--kv-gutter); }

	.kv-home .kv-btn {
		gap: var(--kv-btn-gap-md);
		padding: var(--kv-btn-pad-md);
		border-radius: var(--kv-btn-radius-md);
		font-size: var(--kv-fs-sub2); line-height: var(--kv-lh-sub2);
	}
	.kv-home .kv-btn--secondary {
		border-width: var(--kv-btn-stroke-md);
		padding: calc(12px - var(--kv-btn-stroke-md)) calc(20px - var(--kv-btn-stroke-md));
	}

	.kv-site .kv-hfaq__head h2,
	.kv-site .kv-hblogs__head h2,
	.kv-site .kv-hgal__head h2,
	.kv-site .kv-habout__h,
	.kv-site .kv-promo__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-site .kv-hero__h { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }

	/* The browse-card bands lose their arrows and their dots here, nodes
	   2:23370 and 2:23382: the card cut by the edge of the screen is the whole
	   of the affordance on a phone. The reviews keep their dots. */
	.kv-cards__head .kv-arrows,
	.kv-cards > .kv-cards__dots { display: none; }

	/* Questions, blogs and gallery: back to the left, button under the band. */
	.kv-site .kv-hfaq__head > h2,
	.kv-hblogs__head > div,
	.kv-hgal__head > div { margin: 0 0 24px; text-align: left; }
	.kv-site .kv-hblogs__head h2,
	.kv-site .kv-hgal__head h2 { margin: 0 0 16px; }
	.kv-hfaq__head > .kv-btn,
	.kv-hblogs__head > .kv-btn,
	.kv-hgal__head > .kv-btn { margin: 24px auto 0 0; }

	/* The carousels keep the centre. */
	.kv-prow--home > .kv-prow__head > h2 { margin: 0 0 24px; text-align: center; }
	.kv-prow--home > .kv-prow__head > .kv-btn { margin: 24px auto 0; }

	.kv-hfaq__grid { grid-template-columns: 1fr; gap: 24px; }

	/* Node 2:23440: the cards stack and stop scrolling. */
	.kv-hblogs__grid {
		display: grid; grid-auto-flow: row; grid-template-columns: 1fr;
		grid-auto-columns: auto; gap: 24px;
		margin-right: 0; padding-right: 0; overflow: visible;
	}

	/* Node 2:23448: two squares over one wide one, and nothing after that. */
	/* Node 2:23448: two squares and a band under them. The band is the second
	   picture again, the fourth takes the square beside the first, and the
	   column has nowhere to go here, so it is the one that drops. */
	.kv-hgal__grid { grid-template-columns: repeat(2, 1fr); gap: 15px; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(1) { grid-column: 1; grid-row: 1; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(2) { grid-column: 1 / span 2; grid-row: 2; aspect-ratio: 343 / 164; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(3) { display: none; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(4) { grid-column: 2; grid-row: 1; aspect-ratio: 1; }
	.kv-hgal__grid > .kv-gal__tile:nth-child(n + 5) { display: none; }

	/* Node 2:23434: the button goes back to the left with everything else. */
	.kv-habout { gap: 24px; }
	.kv-habout__media { height: 240px; border-radius: 8px; }
	.kv-habout__cta { justify-content: flex-start; }

	.kv-promo { min-height: 272px; }
	.kv-promo__words { gap: 24px; padding: 36px var(--kv-gutter); }
	.kv-promo__cta { margin: 0; }
}

/* ---------------------------------------------------------------------------
   Signing in, nodes 2:33145, 2:33193, 2:33256 and 2:33289

   One card, four panels, and the same card whether it arrives as an overlay
   over the page or as the account page itself. `.kv-overlay--page` is the second
   case: no scrim, no dialog, everything else identical.
   ------------------------------------------------------------------------ */

dialog.kv-overlay {
	width: 100%; max-width: 100vw; max-height: 100vh; height: 100%;
	margin: 0; padding: var(--kv-gutter); border: 0; background: none;
	display: none; place-items: center; overflow: auto;
}
dialog.kv-overlay[open] { display: grid; }
/* Node 2:33361: Others/Background Overlay, black at 40%. It had been the
   brand's near-black at 92%, which shut the page out rather than dimming it. */
dialog.kv-overlay::backdrop { background: rgba(0, 0, 0, .4); }

.kv-overlay__card {
	position: relative;
	/* Node 2:33146 is 460 across, with 32 of padding leaving a 396 field.
	   It had been built at 326, which read as a column on a phone blown up
	   on a desktop. */
	width: 100%; max-width: 460px;
	display: flex; flex-direction: column; gap: 24px;
	padding: 32px; border-radius: 12px;
	background: var(--kv-paper); box-shadow: var(--kv-elevation-3);
}

/* The cross, added 14.10.2026 at the client's request: they went looking for
   one rather than pressing outside the card. The frames draw none, so the
   press is the cart pop-up's, which is the design system's own close control:
   40 by 40 inset 2 from the corner, a 24 icon, Text/Secondary. It is printed
   only inside the dialog, so the account page's copy of the same cards, which
   has nothing to close, does not grow one.

   The heading is centred and the card is padded 32, so the cross sits in that
   padding and the two can meet: `Vi har fått forespørselen` reached 7px under
   it at 375. The card takes the clearance at the top instead of the heading
   taking it at the sides, because a side padding wide enough to be safe at
   every width wraps short headings that fit perfectly well, and this costs 16
   of height in the dialog and nothing anywhere else. The account page's copy
   of the card is untouched. */
.kv-overlay__close {
	position: absolute; top: 2px; right: 2px; z-index: 2;
	width: 40px; height: 40px;
	display: grid; place-items: center;
	padding: 0; border: 0; background: none; cursor: pointer; color: var(--kv-text-2);
}
.kv-overlay__close:hover,
.kv-overlay__close:focus-visible { color: var(--kv-text); }
.kv-overlay .kv-overlay__close .karivarah-icon { width: 24px; height: 24px; }
dialog.kv-overlay .kv-overlay__card { padding-top: 48px; }

.kv-overlay--page { display: grid; place-items: center; padding: 64px var(--kv-gutter); }

/* Two classes deep: the overlay's heading is an `h2`, and the kit sets `h2`
   with a class and an element, which beat the bare class and drew it at 40/56
   however many times the rules below said otherwise. */
.kv-overlay .kv-overlay__h {
	margin: 0; text-align: center;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); color: var(--kv-text);
}
.kv-overlay__lead {
	margin: -8px 0 0; text-align: center;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2);
}
.kv-overlay__panel { display: flex; flex-direction: column; gap: 24px; }
.kv-overlay__form { display: flex; flex-direction: column; gap: 16px; margin: 0; }
.kv-overlay__submit { width: 100%; justify-content: center; margin-top: 8px; }

/* The two links that are buttons, because they switch a panel rather than go
   anywhere. They are typed as text so nothing about them reads as a control. */
.kv-overlay .kv-overlay__link,
.kv-overlay .kv-overlay__link:hover,
.kv-overlay .kv-overlay__link:focus {
	padding: 0 !important; border: 0 !important; background: none !important;
	font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	color: var(--kv-text) !important; text-decoration: underline; cursor: pointer;
}
.kv-overlay .kv-overlay__link:hover { color: var(--kv-primary) !important; }

/* ---------------------------------------------------------------------------
   Signing in without a password, 11.10.2026
   -------------------------------------------------------------------------*/

/* What a panel says back. Hidden until it has something to say, so the card
   does not keep a gap for a sentence that may never come. */
.kv-auth__msg {
	margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	color: var(--kv-error-dark);
}

/* The code is six digits read off a phone and typed with a thumb, so it is set
   wide and large enough to check against the letter without squinting. */
.kv-auth [name="kv_auth_code"] {
	font-size: var(--kv-fs-h5); letter-spacing: .32em; font-variant-numeric: tabular-nums;
}

/* The address that has already been proven. It is still a field, because it is
   what the form posts back, but nothing about it should invite a cursor. */
.kv-auth .kv-field__input[readonly] { color: var(--kv-text-2); cursor: default; }
.kv-auth .kv-field__input[readonly]:focus { border-color: var(--kv-grey-400); box-shadow: none; }

/* Asking again, and the wait before it is allowed. The button is a link, so
   the disabled state is the site's global half opacity rather than a grey box. */
.kv-auth__resend { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 8px 0 0; }
.kv-overlay .kv-auth__resend .kv-overlay__link:disabled { opacity: .5; cursor: default; text-decoration: none; }
.kv-overlay .kv-auth__resend .kv-overlay__link:disabled:hover { color: var(--kv-text) !important; }
.kv-auth__wait { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }

/* The two ticks. The second is optional and reads as the quieter of the two. */
.kv-auth__consent { align-items: flex-start; margin: 4px 0; }
.kv-auth__consent span { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

/* ---------------------------------------------------------------------------
   The card against its frames, 09.10.2026

   Nodes 2:33146 log in and 2:33194 register on a desktop, 2:33362 on a phone.
   Everything below is measured off those three. The fields keep the floating
   label the rest of the site uses rather than the frame's plain placeholder,
   which is a standing decision, but they take the frame's height, radius and
   type.
   ------------------------------------------------------------------------ */

/* The card's children fill it. This read `align-items: center`, which makes
   every child of a flex column shrink to its own contents: the panel inside
   collapsed to the width of the widest thing in it, usually the captcha, and
   the fields came out at about 216 instead of the 396 the frame leaves. The
   heading, the lead and the swap line centre their own text, so nothing
   needed the alignment; what did need centring is the captcha, which brings
   its own width and is centred on its own below. */
.kv-overlay__card { align-items: stretch; }
.kv-overlay__card .prosopo-procaptcha-wp__wrapper { display: flex; flex-direction: column; align-items: center; }

/* The captcha's place, held before it draws. Its scripts load when the form
   is used (inc/forms.php), so without this the form grows by 80px under the
   visitor's hand. 95px is what the widget measures drawn, at every width. */
.kv-site .prosopo-procaptcha-wp__wrapper { min-height: 95px; }

/* ---------------------------------------------------------------------------
   The consent banner (Complianz)

   Complianz draws the banner, its preferences and the "manage consent" tab;
   the site's own parts dress them, so the first thing a visitor sees looks
   like the shop: the overlay card's radius, padding and elevation, Fixel on
   the type ladder, the primary button to accept and the outlined button for
   the other two choices, given equal weight, and the pop-ups' cross. Set
   through Complianz's own variables where it has one, on the banner itself,
   which outranks its `:root` whatever order the stylesheets load in; and two
   classes deep where it has none, which outweighs its one-class rules. The
   frames draw no banner. 15.10.2026.
   ------------------------------------------------------------------------ */
.kv-site .cmplz-cookiebanner,
.kv-site #cmplz-manage-consent {
	--cmplz_banner_background_color: var(--kv-paper);
	--cmplz_banner_border_color: var(--kv-grey-600);
	--cmplz_banner_border_radius: var(--kv-radius);
	--cmplz_banner_width: 460px;
	--cmplz_banner_margin: 12px;
	--cmplz_text_color: var(--kv-text);
	--cmplz_hyperlink_color: var(--kv-primary);
	--cmplz_text_font_size: var(--kv-fs-body2);
	--cmplz_text_line_height: var(--kv-lh-body2);
	--cmplz_title_font_size: var(--kv-fs-sub1);
	--cmplz_link_font_size: var(--kv-fs-body2);
	--cmplz_button_font_size: var(--kv-fs-sub2);
	--cmplz_button_border_radius: var(--kv-btn-radius-md);
	--cmplz_button_accept_background_color: var(--kv-primary);
	--cmplz_button_accept_border_color: var(--kv-primary);
	--cmplz_button_accept_text_color: var(--kv-white);
	--cmplz_button_deny_background_color: transparent;
	--cmplz_button_deny_border_color: var(--kv-text);
	--cmplz_button_deny_text_color: var(--kv-text);
	--cmplz_button_settings_background_color: transparent;
	--cmplz_button_settings_border_color: var(--kv-text);
	--cmplz_button_settings_text_color: var(--kv-text);
	--cmplz_slider_active_color: var(--kv-primary);
	--cmplz_slider_inactive_color: var(--kv-black-200);
	--cmplz_slider_bullet_color: var(--kv-white);
	--cmplz_category_header_always_active_color: var(--kv-success-text);
	--cmplz_category_header_title_font_size: var(--kv-fs-body1);
	--cmplz_category_header_active_font_size: var(--kv-fs-body2);
	--cmplz_category_body_font_size: var(--kv-fs-body2);
	font-family: var(--kv-font);
}

.kv-site .cmplz-cookiebanner { padding: 32px; gap: 16px; box-shadow: var(--kv-elevation-3); }
.kv-site .cmplz-cookiebanner .cmplz-title {
	font-weight: var(--kv-weight-semibold); line-height: var(--kv-lh-sub1); color: var(--kv-text);
}

/* The pop-ups' cross (`.kv-overlay__close`): 40 square, Phosphor's `x` at 24,
   Text/Secondary, darker on hover and focus, and no box. Complianz draws its
   cross with a Font Awesome glyph, a third icon set, so that is hidden and
   Phosphor's drawn in its place as a mask in the current colour. Complianz
   also moves focus to the cross when the banner opens, which made browsers
   draw their focus box round it on arrival; the site's cross shows focus by
   colour alone, so this one does too. Reported by the client 15.10.2026.
   Since the same evening the cross is switched off (Complianz's close_button,
   tools/complianz-config.php), and Complianz hides it with `display: none`:
   nothing here sets `display`, so that setting alone decides, and turning it
   back on brings the cross back in this style. */
.kv-site .cmplz-cookiebanner .cmplz-close {
	position: relative;
	width: 40px; height: 40px; margin: -8px -8px 0 0;
	padding: 0; border: 0; border-radius: 0; background: none; color: var(--kv-text-2);
	outline: none; box-shadow: none;
}
.kv-site .cmplz-cookiebanner .cmplz-close svg { display: none; }
.kv-site .cmplz-cookiebanner .cmplz-close::before {
	content: ""; position: absolute; inset: 0; margin: auto;
	width: 24px; height: 24px; background: currentColor;
	-webkit-mask: url("assets/icons/regular/x.svg") center / contain no-repeat;
	mask: url("assets/icons/regular/x.svg") center / contain no-repeat;
}
.kv-site .cmplz-cookiebanner .cmplz-close:hover,
.kv-site .cmplz-cookiebanner .cmplz-close:focus,
.kv-site .cmplz-cookiebanner .cmplz-close:focus-visible { font-size: inherit; line-height: inherit; color: var(--kv-text); outline: none; }

/* The category switches. Complianz rings a focused switch in blue on every
   focus, a click included; the site rings keyboard focus only, in its own
   colour, 2 offset 2. Reported by the client 15.10.2026. */
.kv-site .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:focus + .cmplz-label::before { box-shadow: none; }
.kv-site .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:focus { outline: none; }
.kv-site .cmplz-cookiebanner .cmplz-categories .cmplz-category .cmplz-banner-checkbox input.cmplz-consent-checkbox:focus-visible + .cmplz-label::before {
	outline: 2px solid var(--kv-primary); outline-offset: 2px;
}

/* Complianz's own heavier shadow on the open banner, and a deeper one on hover,
   outranked the card's. The card's shadow falls downward only, which left the
   banner's top edge melting into a white page, so a second, upward shadow
   marks it, the same one the phone sheet carries. Asked for by the client
   15.10.2026. */
.kv-site .cmplz-cookiebanner.cmplz-show,
.kv-site .cmplz-cookiebanner.cmplz-show:hover { box-shadow: 0 -12px 24px -4px rgba(158, 158, 158, 0.24), var(--kv-elevation-3); }

/* On a phone Complianz turns the banner into a sheet the width of the screen,
   white on a white page with nothing to say where it starts, and hides its
   heading below 426. The heading comes back, and the sheet gets the card's
   radius on its top corners, a hairline edge and the card's shadow turned to
   cast upward, so it reads as a panel over the page. Reported by the client
   15.10.2026. */
@media (max-width: 768px) {
	.kv-site .cmplz-cookiebanner.cmplz-show,
	.kv-site .cmplz-cookiebanner.cmplz-show:hover {
		border-radius: var(--kv-radius) var(--kv-radius) 0 0;
		border-top: 1px solid var(--kv-grey-600);
		box-shadow: 0 -12px 24px -4px rgba(158, 158, 158, 0.24);
	}
}
@media (max-width: 425px) {
	.kv-site .cmplz-cookiebanner .cmplz-header .cmplz-title { display: block; }
}


/* The medium button, nodes 1:857 and 1:876: the stroke is inside its padding. */
.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn {
	min-height: calc(24px + var(--kv-lh-sub2));
	padding: calc(12px - var(--kv-btn-stroke-md)) calc(20px - var(--kv-btn-stroke-md));
	border-width: var(--kv-btn-stroke-md);
	font-family: var(--kv-font); font-weight: var(--kv-weight); line-height: var(--kv-lh-sub2);
	transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s;
}
.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-accept:active { background: var(--kv-primary-dark); border-color: var(--kv-primary-dark); }
.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-accept:focus-visible { box-shadow: var(--kv-elevation-primary); }
.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn:not(.cmplz-accept):focus-visible {
	border-color: var(--kv-primary-light); color: var(--kv-primary);
}
.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn:not(.cmplz-accept):active {
	background: var(--kv-primary-4); border-color: var(--kv-primary-light); color: var(--kv-primary);
}
@media (hover: hover) {
	.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn.cmplz-accept:hover { box-shadow: var(--kv-elevation-primary); }
	.kv-site .cmplz-cookiebanner .cmplz-buttons .cmplz-btn:not(.cmplz-accept):hover {
		border-color: var(--kv-primary-light); color: var(--kv-primary);
	}
}

/* The policy links under the buttons. */
.kv-site .cmplz-cookiebanner .cmplz-links .cmplz-link { color: var(--kv-text-2); text-decoration: underline; text-underline-offset: 2px; }
.kv-site .cmplz-cookiebanner .cmplz-links .cmplz-link:hover { color: var(--kv-primary); }

/* The tab that reopens the choices. */
.kv-site #cmplz-manage-consent .cmplz-manage-consent {
	font-family: var(--kv-font); font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	box-shadow: var(--kv-elevation-3);
}

/* SemiBold/H4 at 30/40, not the H5 it was built at, and H5 on a phone, nodes
   2:33147 and 2:33347. */
.kv-overlay .kv-overlay__h { font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }

/* 20 between the fields, node 2:33149. */
.kv-overlay__form { gap: 20px; }

/* Node 2:33150 is 48 tall: 12 of padding over a 16/24 line and a 12 radius. */
.kv-overlay__card .kv-field .kv-field__input { padding: 11px 16px; border-radius: 12px; }
.kv-overlay__card .kv-field__label { left: 16px; top: 12px; }
.kv-overlay__card .kv-field .kv-field__input:focus,
.kv-overlay__card .kv-field .kv-field__input:not(:placeholder-shown) { padding-top: 18px; padding-bottom: 4px; }
.kv-overlay__card .kv-field__input:focus + .kv-field__label,
.kv-overlay__card .kv-field__input:not(:placeholder-shown) + .kv-field__label { transform: translateY(-8px); }

/* Node 2:33202: a 20 box with a 4 radius, 10 from its sentence, and the
   sentence Regular/Body 2 in Text/Secondary. */
.kv-overlay__card .kv-check { gap: 10px; }
.kv-overlay__card .kv-check input { flex-basis: 20px; width: 20px; height: 20px; margin: 4px 0 0; border-radius: 4px; }
.kv-overlay__card .kv-check label { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }

/* Node 2:33157 is 48 tall with a 12 radius and Regular/Body 1. */
.kv-overlay__card .kv-btn {
	padding: 12px 20px; border-radius: 12px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1);
}

/* -------------------------------------------------------------------------
   The waiting list, 09.10.2026

   Not in the frames. The panel it opens is the overlay's, so all that is left
   here is the button on a sold-out product page and the line its form shows
   when something is refused.
   ------------------------------------------------------------------------ */

.kv-pdp__buy--wait { display: flex; align-items: stretch; gap: 16px; margin-top: 24px; }
.kv-pdp__buy--wait .kv-wait__open { flex: 1 1 auto; justify-content: center; }
.kv-pdp__buy--wait .kv-pdp__wish { flex: 0 0 auto; }
.kv-wait__error { margin: 0; text-align: center; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-error-dark); }

@media (max-width: 767px) {
	/* Node 2:33362: 343 across, 16 of padding, and every step down one. */
	.kv-overlay__card { max-width: 343px; padding: 16px; gap: 24px; }
	.kv-overlay .kv-overlay__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
	.kv-overlay__panel { gap: 20px; }
	.kv-overlay__form { gap: 16px; }
	.kv-overlay__card .kv-field .kv-field__input {
		padding: 11px 16px; border-radius: 10px;
		font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2);
	}
	.kv-overlay__card .kv-field__label { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-overlay__card .kv-check { gap: 8px; }
	.kv-overlay__card .kv-check input { flex-basis: 16px; width: 16px; height: 16px; margin: 2px 0 0; border-radius: 3px; }
	.kv-overlay__card .kv-check label { font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); }
	.kv-overlay--page { padding: 48px var(--kv-gutter); }
}

/* ---------------------------------------------------------------------------
   The account area, nodes 2:29166, 2:29716 and 2:32512

   Two screens in the design are deliberately absent: account details and the
   address set. The shop keeps neither, so there is nothing for them to edit.
   ------------------------------------------------------------------------ */

/* `body.kv-theme-page .site-main` zeroes the padding for the shortcode pages
   that run edge to edge. The account page is a theme page for the page title
   but not for the margins, so this matches that selector's weight to win it
   back rather than losing silently. */
body.woocommerce-account .site-main { max-width: 1440px; margin: 0 auto; padding: 48px var(--kv-gutter) 96px; }
.woocommerce-account .woocommerce { max-width: 1136px; margin-inline: auto; display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 24px 48px; }
/* Signed out there is no column of links, only the sign in card, so the two
   tracks are one. It had been living on the fact that the card happened to be
   the second item in the grid and so landed in the wide track; the moment
   anything was printed above it, the card dropped into the 200px one. */
.woocommerce-account:not(.logged-in) .woocommerce { grid-template-columns: minmax(0, 1fr); }

.kv-site .kv-acct__hello {
	grid-column: 1 / -1; margin: 0 0 24px;
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h3); line-height: var(--kv-lh-h3); color: var(--kv-text);
}
/* The commissioned wave, traced into the set's own format on 08.10.2026. It
   takes the heading's ink rather than a colour of its own. */
.kv-acct__wave { display: inline-flex; vertical-align: baseline; margin-left: 12px; }
.kv-acct__wave .karivarah-icon { width: 1em; height: 1em; }

/* WooCommerce's own layout floats the two columns and gives them 30% and 68%.
   Float is ignored on a grid item but the widths are not, so the nav was
   shrinking to 30% *of its own column*, 66px, and the words spilled out of
   the box behind them. The grid does the columns; these two take their
   widths back. */
.woocommerce-account .woocommerce .kv-acct__nav,
.woocommerce-account .woocommerce .woocommerce-MyAccount-content {
	float: none; width: auto; min-width: 0;
}

/* Nodes 2:29173 and 2:29192. Every item is Text/Primary at Body 1 with a 24px
   mark, 8px between mark and words, 12px between items, and 12 by 8 of padding
   inside a radius of 8. */
.kv-acct__nav { align-self: stretch; }
.kv-acct__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; min-height: 100%; }
.kv-acct__item a {
	display: flex; align-items: center; gap: 8px;
	/* A 40 row 12 from the next, node 2:28797. The mark inside is 32 rather
	   than the frame's 24, because the commissioned set carries a floor, so
	   the padding gives way instead of the row. */
	padding: 4px 12px; border-radius: 8px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text) !important; text-decoration: none;
}
.kv-acct__item.is-active a { background: var(--kv-primary-8, var(--kv-primary-8)); color: var(--kv-primary) !important; }
.kv-acct__item.is-active a .karivarah-icon { color: var(--kv-primary); }
/* The frames draw a default and a current, and no hover. A pointer still needs
   an answer, so it borrows the current state's own tint rather than inventing
   a colour. */
.kv-acct__item:not(.is-active) a:hover { background: var(--kv-primary-4); }

/* Contact and log out sit at the foot of the column, node 2:29172, which draws
   them below the four with the space between. Log out is Error/Main, which is
   its own colour and not the primary. */
.kv-acct__item--apart:first-of-type { margin-top: auto; padding-top: 48px; }
.kv-acct__item--apart:last-child a,
.kv-acct__item--apart:last-child a .karivarah-icon { color: var(--kv-error) !important; }

/* Closing the account is the last thing in the column and the quietest in it.
   A step that cannot be undone should be findable rather than prominent, log
   out above it already has the error colour, and two reds at the foot of a
   column would say neither is the serious one. The dialog carries the warning.
   It is a button and not a link, because it opens the overlay and goes
   nowhere, so it is given the shape the links have. */
.kv-acct__item--delete > button {
	display: flex; align-items: center; gap: 8px; width: 100%;
	padding: 8px 12px !important; border: 0 !important; border-radius: 8px !important;
	background: none !important; box-shadow: none !important;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); font-weight: var(--kv-weight);
	color: var(--kv-text-2) !important; text-align: left; cursor: pointer;
}
.kv-acct__item--delete > button .karivarah-icon { width: 24px; height: 24px; flex: 0 0 24px; color: var(--kv-text-2); }
.kv-acct__item--delete > button:hover { background: var(--kv-primary-4) !important; }

/* The farewell, over the sign in card they land on. The account page lays its
   two columns out with a grid, and a notice dropped into it took the first
   column and stood in the margin; it spans the row instead and is held to the
   card's own 460 so the two read as one thing. */
.woocommerce-account .woocommerce > .kv-notes {
	grid-column: 1 / -1;
	width: 100%; max-width: 460px;
	margin: 0 auto 24px;
}

/* ---------------------------------------------------------------------------
   Angre kjøpet her

   Three panels in the overlay. The first is the sign in card with two other
   fields in it; the second borrows the cart pop-up's own furniture, node
   2:34291, the scrolling list and the foot that stays put, because that is
   already a sticky summary over a list of bought things and this is the same
   job. The row is the cart's row with a tick where Remove was and a stepper
   that counts back rather than up.
   ------------------------------------------------------------------------ */

/* The card widens for the lines and only for the lines. The cart pop-up is
   600 and so is this; everything else in the overlay stays at 460. Above the
   phone only, because down there the card is 343 and this rule comes later in
   the file than the one that says so. */
@media (min-width: 768px) {
	.kv-overlay__card:has(> [data-kv-overlay-panel="return-lines"]:not([hidden])) { max-width: 600px; }
}

.kv-withdraw {
	padding: 0; border: 0; background: none; cursor: pointer; text-align: left;
	font: inherit; color: inherit;
}
.kv-withdraw:hover { color: var(--kv-primary); text-decoration: underline; }

/* The lines panel has no heading, so its one line of instruction reads from
   the left like the words above a form rather than a title over a card. */
[data-kv-overlay-panel="return-lines"] .kv-overlay__lead { margin: 0; text-align: left; }

.kv-ret__order { margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-ret__late,
.kv-ret__none { margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
/* The site's own error notice, at the top of the card the way the cart pop-up
   carries its own, node 2:34110. */
.kv-ret__note { width: 100%; }

.kv-ret { display: flex; flex-direction: column; gap: 20px; }
/* The foot is the pop-up's, pulled back out to the card's edges so the rule
   above it runs the width of the card the way it does in the cart. */
.kv-ret__foot { margin: 0 -32px -32px; }

/* The row is the cart's row and nothing here resizes it. Node 2:34303 is
   518 by 150: a 150 picture, 16 of gap, a 222 column of words, 16, and a 114
   column holding the stepper and the price. The theme already draws that, so
   the only rules below are for the two controls that change hands, and the
   measurements are left where they were measured.

   What was wrong before: this block shrank the picture to 72, closed the gap
   to 12 and let the stepper size itself, so the row was its own thing wearing
   the cart's classes. */

/* The tick sits under the name and the two reasons under the tick, because
   ticking is what wakes the reasons: the control that governs comes first.
   It still wears Remove's type and colour, node I2:34303;2:26991. All three
   are one block now, so the body centres it against the picture the way the
   cart centres its own two groups. */
.kv-ret__row .kv-cartrow__body { justify-content: center; }
.kv-ret__pick { align-self: flex-start; align-items: center; gap: 4px; }
.kv-ret__pick span { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); cursor: pointer; }
.kv-ret__pick input { margin: 0; }

/* The words say whether the line is marked, not whether the pointer happens to
   be over them. Remove is a link and goes Primary/Main on hover, so the tick
   had borrowed that, and a hover does not come back off on its own: the
   pointer sits where it clicked, and on a touch screen it stays until
   something else is tapped, so an unticked line went on reading as ticked.
   The colour follows the control now, and the box keeps the grey ring that
   node 1:1814 draws on hover. A reason that is still asleep stays grey, which
   is why the ticked test asks for an enabled one. */
.kv-ret__pick:has(input:checked) span,
.kv-ret__kinds .kv-check:has(input:checked:not([disabled])) span { color: var(--kv-primary); }

/* The two reasons take the colour and size lines' place, node I2:34303;2:26984.
   The cart holds that slot at exactly 50 and hides whatever will not fit,
   which is right for "Farge: Beige" and wrong for a label long enough to wrap:
   it cut the second radio in half down the middle. The 50 becomes a floor
   instead of a ceiling, so rows stay level until something needs the room. */
.kv-ret__kinds {
	flex-direction: row; align-items: center; flex-wrap: wrap; gap: 2px 16px;
	height: auto; min-height: 50px; overflow: visible;
}
.kv-ret__kinds .kv-check { align-items: center; gap: 6px; }
.kv-ret__kinds .kv-check span { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); cursor: pointer; }
.kv-ret__kinds .kv-check input { margin: 0; }

.kv-ret__total { font-weight: var(--kv-weight-semibold); }
.kv-ret__fault { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }

/* The button on an order card in the account, beside the other two links. */
.kv-order__return {
	padding: 0; border: 0; background: none; cursor: pointer; font: inherit;
	color: var(--kv-primary); text-decoration: underline;
}

@media (max-width: 767px) {
	/* The card is 343 here, so the row gives up its picture rather than
	   squeezing the words, and the foot follows the narrower padding. */
	.kv-ret__foot { margin: 0 -16px -16px; padding: 16px; }

	/* The cart row keeps its own phone layout, picture and all. The only thing
	   said here is that the two controls come down with the rest of the row
	   rather than being left behind at 16. */
	.kv-ret__pick span,
	.kv-ret__kinds .kv-check span { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-ret__kinds { gap: 2px 12px; min-height: 42px; }

	/* Below about 350 the picture still wants its 120 and the stepper and the
	   price no longer fit on one line beside it. They wrap rather than running
	   off the edge of the card, where the list's scroll would cut the price. */
	.kv-ret__row .kv-cartrow__side { flex-wrap: wrap; gap: 4px 8px; }
}

/* The dialog's own line, between the lead and the two answers. */
.kv-del__note { margin: 0 0 8px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); text-align: center; }

/* Node 2:29202: SemiBold/H4, 12px above the Grey/600 rule and 32 below it. */
.kv-site .kv-acct__h {
	margin: 0 0 32px; padding-bottom: 12px; border-bottom: 1px solid var(--kv-grey-600);
	font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); color: var(--kv-text);
}

/* WooCommerce prints the two address headings with no class of their own, so
   the kit's `h2` was drawing them at 40 and "Leveringsadresse" alone was wider
   than the column on a phone. They are the panel's own heading, node 2:31466. */
.kv-site .woocommerce-Address-title h2 {
	margin: 0; font-weight: var(--kv-weight-semibold);
	font-size: var(--kv-fs-sub1); line-height: var(--kv-lh-sub1); color: var(--kv-text);
}

.kv-acct__empty { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 64px 0; text-align: center; }
/* The same mark the empty cart carries, nodes 2:33039 and 2:29612: a 112
   circle in the soft tint with a 64 commissioned mark in it. */
.kv-acct__empty-mark {
	display: grid; place-items: center;
	padding: 24px; border-radius: 1000px;
	background: var(--kv-primary-4); color: var(--kv-primary-light);
}
.kv-acct__empty-mark .karivarah-icon { width: 64px; height: 64px; }
@media (max-width: 767px) {
	.kv-acct__empty-mark { padding: 16px; }
	.kv-acct__empty-mark .karivarah-icon { width: 48px; height: 48px; }
}
.kv-acct__empty p { margin: 0; max-width: 360px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }

/* The order cards, node 2:29169 */

/* The card is Primary/Shades/4p, not a grey. The warm tint is the primary at
   four percent, which is the same ink as the current item in the column and
   is why a grey looked wrong beside it. Node 2:29206: 24 of padding, the head
   16 above the facts, the pictures 24 below them. */
.kv-orders { display: flex; flex-direction: column; gap: 24px; }

/* Two columns and three rows, because the same four children are dealt twice.
   Node 2:29206 puts the actions on the number's row and the money at the end
   of the facts; nodes 2:29347 and 2:29479 send the money and the actions to a
   row of their own under the pictures. Areas rather than a wrapper, so the
   markup is written once and neither arrangement is the odd one out. */
.kv-order {
	display: grid; align-items: start;
	grid-template-columns: minmax(0, 1fr) auto;
	grid-template-areas:
		"id      actions"
		"facts   sum"
		"pics    pics";
	gap: 16px;
	padding: 24px; border-radius: 12px; background: var(--kv-primary-4);
}
.kv-site .kv-order__id { grid-area: id; margin: 0; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }

/* Node 2:29210: the two actions 12 apart with a Grey/800 hairline between. */
.kv-order__actions { grid-area: actions; display: flex; align-items: center; gap: 12px; margin: 0; }
.kv-order__actions a { display: inline-flex; align-items: center; gap: 6px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-primary) !important; }
.kv-order__actions a + a { border-left: 1px solid var(--kv-grey-800); padding-left: 12px; }

/* Node 2:29214: groups 32 apart, label over value with 6 between, and every
   line Body 1. The labels were at caption and the values a step down, which
   is most of what looked wrong. */
.kv-order__facts,
.kv-vieworder__facts { display: flex; flex-wrap: wrap; gap: 16px 32px; margin: 0; }
.kv-order__facts dt,
.kv-order__sum dt,
.kv-vieworder__facts dt { display: flex; align-items: center; gap: 4px; margin: 0 0 6px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-order__facts dd,
.kv-order__sum dd,
.kv-vieworder__facts dd { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-order__facts { grid-area: facts; }
.kv-order__sum { grid-area: sum; display: block; margin: 0; text-align: right; }
.kv-order__sum dt { justify-content: flex-end; }

.kv-order__pics { grid-area: pics; list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; padding: 0; }
.kv-order__pics img { width: 96px; height: 96px; object-fit: cover; border-radius: 8px; display: block; }

/* One order, nodes 2:29716, 2:30297 and 2:30879 */

/* The two panel headings are different steps on purpose: node 2:29203 draws
   My orders at SemiBold/H4 and node 2:29752 draws Order details at H5. */
.kv-site .kv-vieworder .kv-acct__h { font-size: var(--kv-fs-h5); line-height: var(--kv-lh-h5); }
.kv-vieworder__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.kv-vieworder__head .kv-acct__h { flex: 1 0 100%; }
/* Node 2:29758: Regular/H6, not the card's SemiBold/Body 1. */
.kv-site .kv-vieworder__id { margin: 0; font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
/* Order numbers are long enough now that the link no longer fits beside one,
   so it takes a row of its own and stays at the right of it. */
.kv-vieworder__invoice { flex: 1 0 100%; margin: 0; text-align: right; }
.kv-vieworder__invoice a { display: inline-flex; align-items: center; gap: 4px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-primary) !important; }
.kv-vieworder__facts { margin: 16px 0 32px; }

/* The three stages. The line behind them is one gradient stop per stage, so
   the filled part always ends under the mark it belongs to. */

/* Node 2:29786 draws no panel here at all: the words sit on the paper. Both
   the grey and the tint that preceded it were wrong, and the right answer was
   to stop painting a box. */
.kv-vieworder__stage { margin-bottom: 32px; }
.kv-vieworder__stage-h { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-primary); }
.kv-vieworder__stage-when { margin: 2px 0 12px; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-vieworder__stage-note { margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
/* A request we have not answered yet, in the brand colour so it reads as
   something live rather than as another sentence about the parcel. */
.kv-vieworder__pending { margin-top: 8px; color: var(--kv-primary); }
/* The same step as "Last ned faktura" at the head of this page, because they
   are the same kind of thing and sat a size apart. */
.kv-vieworder__return { margin: 16px 0 0; }
.kv-vieworder__return .kv-order__return { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }

.kv-vieworder__items { list-style: none; margin: 0 0 32px; padding: 0; display: flex; flex-direction: column; gap: 16px; }
/* One line of an order, node 2:29792. Everything on it is Regular/Body 1: the
   name in Text/Primary, the attributes and the quantity in Text/Secondary. */
.kv-oitem { display: grid; grid-template-columns: 96px minmax(0, 1fr) auto; gap: 12px; align-items: center; }
.kv-oitem__pic img { width: 96px; height: 96px; object-fit: cover; border-radius: 8px; display: block; background: #FFFFFF; }
.kv-oitem__words { display: flex; flex-direction: column; gap: 6px; padding: 4px 0; min-width: 0; }
/* Node 2:29796 clips at 48px, which is two lines of it. */
.kv-oitem__name {
	display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
/* Node 2:29801 puts a hairline between the pairs, and it belongs between them
   rather than before them: once the row wraps, a pair that begins a line has
   nothing on its left to be divided from. No breakpoint can know which pairs
   those are, because it depends on how long the words are, so the rule is a
   pseudo-element hanging off the pair's left and the row is clipped. A pair
   that starts a line puts its rule at -13px, outside the box, and it is cut
   off; a pair further along the line puts it in the gap, and it shows.

   The rows are 6px apart, the same step the name sits above them by, and the
   columns 25px, which is the frame's 12 either side of the 1px rule. */
.kv-oitem__meta {
	display: flex; flex-wrap: wrap; overflow: hidden;
	column-gap: 25px; row-gap: 6px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2);
}
.kv-oitem__pair { position: relative; display: flex; align-items: center; gap: 4px; white-space: nowrap; }
.kv-oitem__pair + .kv-oitem__pair::before {
	content: ""; position: absolute; top: 0; bottom: 0; left: -13px;
	width: 1px; background: var(--kv-grey-800);
}
.kv-oitem__money { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; white-space: nowrap; }
.kv-oitem__price { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-oitem__qty { font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }

.kv-vieworder__foot { display: grid; grid-template-columns: 1fr 1fr; gap: 32px 48px; }
/* Nodes 2:29867 and 2:29896 draw both of these at Regular/H6. Two classes
   deep so the Elementor kit, which styles h1 to h6 at one class and one
   element, does not take the weight back. */
.kv-site .kv-vieworder__foot h3 { margin: 0 0 20px; font-weight: 400; font-size: var(--kv-fs-h6); line-height: var(--kv-lh-h6); color: var(--kv-text); }
/* Node 2:29869: the label and the thing it names are both Regular/Body 1, 8px
   apart, with 12px between one pair and the next. */
.kv-vieworder__label { margin: 12px 0 8px; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text-2); }
.kv-vieworder__label:first-of-type { margin-top: 0; }
.kv-vieworder__value { margin: 0; font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text); }
.kv-vieworder__value address { font-style: normal; }
/* Node 2:29897. Every row is Regular/Body 1 in Text/Primary, 12px apart, and
   the rule above the total is 12px under the row before it and 12px over the
   total's own words, which the flex gap and the padding give between them. */
.kv-vieworder__summary dl { margin: 0; display: flex; flex-direction: column; gap: 12px; }
.kv-vieworder__line {
	display: flex; align-items: center; justify-content: space-between; gap: 16px;
	font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); color: var(--kv-text);
}
.kv-vieworder__line dt, .kv-vieworder__line dd { margin: 0; }
.kv-vieworder__line dd { white-space: nowrap; }
/* Node 2:29903: the figure that comes off, in Error/Light. */
.kv-vieworder__line--discount dd { color: var(--kv-error-dark); }
/* Node 2:29908 is SemiBold/Body 1 over a hairline of Grey/800. */
.kv-vieworder__line--total { border-top: 1px solid var(--kv-grey-800); padding-top: 12px; font-weight: var(--kv-weight-semibold); }

/* The wishlist, node 2:32512, drawn as the shop draws itself.

   The frame's table was replaced on 08.10.2026: a row with a quantity and an
   add to cart cannot serve a variable product, and the catalogue is full of
   them, so the shop's own card does the work and the reader goes to the
   product page to choose.

   The columns are declared here in full rather than leaning on `.kv-grid`'s.
   Those come earlier in this file than this rule, and at equal weight
   the later one wins **in every media query**, so inheriting the phone's two
   columns was never going to happen: the grid stayed at three at every width,
   which is what a Galaxy Z Fold showed at 674px. */

.kv-wishgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kv-wishgrid > li { list-style: none; }

/* The sentinel the observer watches. It carries height so it can be reached,
   and it is hidden until the script takes it over. */
.kv-wishgrid__more { min-height: 1px; padding: 32px 0; text-align: center; }
.kv-wishgrid__loading,
.kv-wishgrid__done { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); color: var(--kv-text-2); }
.kv-wishgrid__done { margin: 32px 0 0; text-align: center; }

.kv-qty { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--kv-grey-600); border-radius: 100px; padding: 2px; }
.kv-qty .kv-qty__step,
.kv-qty .kv-qty__step:hover,
.kv-qty .kv-qty__step:focus {
	width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
	padding: 0 !important; border: 0 !important; border-radius: 100px;
	background: none !important; color: var(--kv-text) !important; cursor: pointer;
}

/* The invoice is its own document, so it carries its own page rules. */

.kv-invoice__page { background: var(--kv-paper); }
.kv-invoice { max-width: 720px; margin: 48px auto; padding: 0 var(--kv-gutter); color: var(--kv-text); }
.kv-invoice__head { display: flex; justify-content: space-between; gap: 32px; flex-wrap: wrap; margin-bottom: 32px; }
.kv-invoice__head h1 { margin: 0 0 8px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-h4); line-height: var(--kv-lh-h4); }
.kv-invoice__head p { margin: 0; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
.kv-invoice__seller { text-align: right; }
.kv-invoice__to { margin-bottom: 32px; }
.kv-invoice__to h2 { margin: 0 0 8px; font-weight: var(--kv-weight-semibold); font-size: var(--kv-fs-body1); line-height: var(--kv-lh-body1); }
.kv-invoice__to address { font-style: normal; font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
.kv-invoice__lines { width: 100%; border-collapse: collapse; font-size: var(--kv-fs-body2); }
.kv-invoice__lines th, .kv-invoice__lines td { padding: 8px 0; text-align: left; border-bottom: 1px solid var(--kv-grey-600); }
.kv-invoice__lines td:last-child, .kv-invoice__lines th:last-child { text-align: right; }
.kv-invoice__note { margin-top: 24px; font-size: var(--kv-fs-caption); line-height: var(--kv-lh-caption); color: var(--kv-text-2); }
.kv-invoice__print { max-width: 720px; margin: 0 auto 64px; padding: 0 var(--kv-gutter); }

@media print {
	.kv-invoice__print { display: none; }
	.kv-invoice { margin: 0; padding: 0; }
}

/* The tablet keeps the column: node 2:29314 draws the same 200 beside a 442
   content area, so nothing collapses until the phone. */
@media (max-width: 1024px) {
	.kv-vieworder__foot { grid-template-columns: 1fr; }

	/* Nodes 2:29347 and 2:29479 deal the card differently from the desktop:
	   the number keeps the top row to itself, and the money and the two
	   actions share a row at the foot, under the pictures. 16 of padding
	   rather than 24, which is what both frames draw. */
	.kv-order {
		grid-template-areas:
			"id    id"
			"facts facts"
			"pics  pics"
			"sum   actions";
		padding: 16px;
	}
	/* Nodes 2:29371 and 2:29503 put the total on that row and nothing else:
	   the count is a desktop line. Hiding it also keeps the figure off two
	   lines, which it went onto at 375, because Norwegian spaces its
	   thousands and the row was breaking at that space. */
	.kv-order__sum { text-align: left; }
	.kv-order__sum dt { display: none; }
	.kv-order__sum dd { white-space: nowrap; }
	.kv-order__actions { justify-self: end; }

	/* The frames run the pictures off the right edge of the card rather than
	   wrapping them: node 2:29497 puts five 64s in a 311 box, so the fifth is
	   half out of the frame. They scroll instead, bleeding into the card's
	   padding so the row starts level with the words and ends at the edge. */
	.kv-order__pics {
		flex-wrap: nowrap; overflow-x: auto;
		margin: 8px -16px; padding: 0 16px;
		overscroll-behavior-x: contain;
	}
	.kv-order__pics > li { flex: 0 0 auto; }
	.kv-order__pics img { width: 72px; height: 72px; }
}

@media (max-width: 767px) {
	.woocommerce-account .woocommerce { grid-template-columns: 1fr; gap: 32px; }

	/* Two columns, filled across so the reading order and the tab order stay
	   the one the markup has: orders and the wishlist on the top row, contact
	   and log out beneath them. The frame stacks six items down two columns;
	   with four, across is the same picture and keeps the pairs together. */
	.kv-acct__nav { align-self: auto; }
	.kv-acct__list {
		display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px; min-height: 0;
	}
	.kv-acct__item a { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-acct__item .karivarah-icon { width: 20px; height: 20px; }
	/* Nothing to push to the foot of a column that is no longer one. */
	.kv-acct__item--apart:first-of-type { margin-top: 0; padding-top: 0; }
	/* And closing the account gets a row of its own under the pairs, rather
	   than a single cell left over beside an empty one. */
	.kv-acct__item--delete { grid-column: 1 / -1; }
	.kv-acct__item--delete > button { font-size: var(--kv-fs-body2); line-height: var(--kv-lh-body2); }
	.kv-acct__item--delete > button .karivarah-icon { width: 20px; height: 20px; flex-basis: 20px; }

	.kv-wishgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 16px; row-gap: 24px; }
	.kv-order__facts { gap: 12px 24px; }
	/* Node 2:29498: 64 here, where the tablet draws 72. */
	.kv-order__pics img { width: 64px; height: 64px; }
}
