/* ==========================================================================
   Linea — reusable component layer.

   theme.json owns tokens (palette, type scale, spacing scale, widths).
   This file owns component geometry and behaviour that block supports cannot
   express: grids, aspect ratios, hairline systems, the header/drawer and the
   plugin-form skin. Never put customer content, colours or copy here.
   ========================================================================== */

:root {
	--linea-gutter: clamp(20px, 4vw, 64px);
	--linea-section: clamp(88px, 10vw, 150px);
	--linea-section-tight: clamp(78px, 8vw, 118px);
	--linea-wrap: 1420px;
	--linea-reading: 820px;
	--linea-header-h: 76px;
	--linea-card-gap: clamp(14px, 1.8vw, 26px);
	--linea-line: var(--wp--preset--color--line);
	--linea-line-on-dark: rgba(255, 255, 255, 0.2);
	--linea-muted-on-dark: rgba(255, 255, 255, 0.72);
}

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
}

/* The header is fixed, so an anchor must stop below it, not under it. */
.linea-section[id],
.linea-contact[id],
[id^="linea-"] {
	scroll-margin-top: calc(var(--linea-header-h) + 16px);
}

/*
 * `clip`, not `hidden`. Both stop a stray full-bleed child from widening the
 * page, but `overflow-x: hidden` computes `overflow-y` to `auto`, which makes
 * the body a scroll container — and a scroll container is where every
 * `position: sticky` inside it looks for its travel. With `hidden` here, no
 * sticky on the site ever engages. `clip` does not create one.
 */
body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: clip;
}

:where(a):focus-visible,
:where(button):focus-visible,
:where(summary):focus-visible,
:where(input, select, textarea):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent-dark);
	outline-offset: 4px;
}

/* Sections sit flush; rhythm comes from equal padding, not margins. */
.wp-site-blocks > main,
.wp-site-blocks > footer {
	margin-top: 0;
}

img {
	max-width: 100%;
	height: auto;
}

/*
 * Any component that becomes a CSS grid or flex row owns its own gap. WP's
 * `is-layout-flow` margin on every child but the first would double it, and in
 * a grid it offsets items inside their cells (rows stop lining up).
 */
.linea-cards > *,
.linea-card > *,
.linea-card__body > *,
.linea-feature > *,
.linea-feature__body > *,
.linea-projects > *,
.linea-project > *,
.linea-project__body > *,
.linea-split > *,
.linea-facts > *,
.linea-fact > *,
.linea-quote-panel > *,
.linea-faq > *,
.linea-scope > *,
.linea-scope-card > *,
.linea-scope-list > *,
.linea-scope-item > *,
.linea-process > *,
.linea-process-card > *,
.linea-price > *,
.linea-price-card > *,
.linea-duration > *,
.linea-duration-card > *,
.linea-local-links > *,
.linea-area > *,
.linea-area__copy > *,
.linea-notes > *,
.linea-notes__item > *,
.linea-rows > *,
.linea-row > *,
.linea-row__head > *,
.linea-prose-split > *,
.linea-section__head > *,
.linea-section__head-copy > *,
.linea-contact__grid > *,
.linea-contact__copy > *,
.linea-contact__details > *,
.linea-form-card > *,
.linea-footer__inner > *,
.linea-footer__grid > *,
.linea-footer__bottom > *,
.linea-header__inner > *,
.linea-header__brand > *,
.linea-header__nav > *,
.linea-hero__inner > *,
.linea-link-strip__inner > * {
	margin-block-start: 0 !important;
}

/*
 * Exceptions to the reset above: these elements are deliberately pushed to the
 * bottom of their flex card with `margin-top: auto`, which the blanket reset
 * would otherwise cancel.
 */
.linea-scope-card :where(h2, h3, h4),
.linea-feature__body .linea-arrow-link {
	margin-block-start: auto !important;
}

/* --------------------------------------------------------------------------
   1. Section frame
   -------------------------------------------------------------------------- */

/*
 * ONE measure for the whole site.
 *
 * The gutter absorbs the centring instead of each child centring itself. Every
 * section is then exactly `--linea-wrap` wide at most, so core's per-child
 * `max-width + margin-inline: auto` resolves to zero and headings, grids,
 * panels and the footer all share one left edge at any viewport. Do not go back
 * to `max-width` + `margin: auto` on individual children — that is what put
 * four different left edges on the page at 1920px.
 */
.linea-section,
.linea-measure {
	padding-inline: max(var(--linea-gutter), calc((100% - var(--linea-wrap)) / 2));
}

.linea-section {
	padding-block: var(--linea-section);
}

.linea-section--tight {
	padding-block: var(--linea-section-tight);
}

.linea-section--flush-top {
	padding-top: 0;
}

/*
 * For a page that opens with a section instead of a full-bleed hero. The header
 * is fixed and stays solid without a hero under it, so the first section has to
 * clear it itself — the canvas template adds no offset of its own.
 */
.linea-section--below-header {
	padding-top: calc(var(--linea-header-h) + clamp(44px, 5vw, 78px));
}

.linea-section--flush-bottom {
	padding-bottom: 0;
}

/* A section that follows another of the same kind breathes a little less. */
.linea-section--stacked {
	padding-top: clamp(78px, 8vw, 112px);
}

.linea-reading {
	max-width: var(--linea-reading);
	margin-inline: auto;
}

/* A closing line of small print under a block of copy — registration number,
   area served, the things that reassure without needing to be read. */
.linea-fineprint {
	max-width: 520px;
	margin-top: 26px !important;
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	line-height: 1.55;
}

.has-dark-background-color .linea-fineprint,
.has-contrast-background-color .linea-fineprint {
	color: rgba(255, 255, 255, 0.55);
}
/* Same fix for the other width-capped blocks that sit directly in a section. */
.linea-section > .linea-reading,
.linea-section > .linea-copy,
.linea-section > p {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* Dark bands ------------------------------------------------------------- */

.linea-section.has-dark-background-color,
.linea-section.has-contrast-background-color {
	color: var(--wp--preset--color--on-dark);
}

.linea-section.has-dark-background-color :where(h1, h2, h3, h4, h5, h6),
.linea-section.has-contrast-background-color :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--on-dark);
}

.linea-section.has-dark-background-color .is-style-eyebrow,
.linea-section.has-contrast-background-color .is-style-eyebrow {
	color: rgba(255, 255, 255, 0.76);
}

.linea-section.has-dark-background-color :where(p:not(.is-style-eyebrow)),
.linea-section.has-contrast-background-color :where(p:not(.is-style-eyebrow)) {
	color: var(--linea-muted-on-dark);
}

/* --------------------------------------------------------------------------
   2. Text roles
   -------------------------------------------------------------------------- */

.is-style-eyebrow {
	margin: 0 0 18px;
	color: var(--wp--preset--color--accent-dark);
	font-size: 15px;
	line-height: 1.4;
	font-weight: 600;
	letter-spacing: 0.005em;
}

.is-style-eyebrow.linea-eyebrow--caps {
	text-transform: uppercase;
	letter-spacing: 0.075em;
}

.is-style-lead {
	color: var(--wp--preset--color--contrast);
	font-size: clamp(19px, 1.7vw, 23px);
	line-height: 1.6;
}

.linea-copy,
.linea-section :where(p.linea-copy) {
	color: var(--wp--preset--color--muted);
	font-size: clamp(16px, 1.35vw, 19px);
	line-height: 1.68;
}

.linea-copy--narrow {
	max-width: 660px;
}

.linea-balance {
	text-wrap: balance;
}

/* Underlined arrow link -------------------------------------------------- */

.linea-arrow-link,
.linea-arrow-link a {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	width: fit-content;
	font-size: 14px;
	font-weight: 600;
}

.linea-arrow-link a {
	border-bottom: 1px solid currentColor;
	padding-bottom: 2px;
	transition: color 0.2s ease, border-color 0.2s ease;
}

/*
 * Same hover as the card read-more: the rule goes `highlight`, the label stays
 * readable. Deliberately identical — these are the same gesture in two
 * different link styles, and giving them different hovers would read as two
 * unrelated systems.
 *
 * `.linea-project:hover` / `.linea-card:hover` are here for the same reason as
 * on `.linea-quiet-link`: those cards cast a full-card `::after` overlay from
 * their linked heading, so the arrow link underneath never receives the
 * pointer. `.linea-feature` has no overlay, so its link hovers on its own.
 */
.linea-project:hover .linea-arrow-link a,
.linea-card:hover .linea-arrow-link a,
.linea-arrow-link a:hover,
.linea-arrow-link a:focus-visible {
	border-color: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--contrast);
}

.has-dark-background-color .linea-arrow-link a:hover,
.has-dark-background-color .linea-arrow-link a:focus-visible,
.has-contrast-background-color .linea-arrow-link a:hover,
.has-contrast-background-color .linea-arrow-link a:focus-visible {
	color: var(--wp--preset--color--on-dark);
}

.linea-arrow-link a::after {
	content: "\2197";
	font-size: 15px;
}

.linea-quiet-link a {
	display: inline-block;
	width: fit-content;
	border-bottom: 1px solid #aaa69d;
	padding-bottom: 2px;
	font-size: 13px;
	font-weight: 600;
	transition: color 0.2s ease, border-color 0.2s ease;
}

/*
 * The rule lights up in `highlight`, the label darkens. Putting the highlight
 * on the text instead would leave 13px type at about 1.9:1 on the card — the
 * underline carries the colour just as clearly and stays readable.
 *
 * The card hover is the important selector here, not the link's own. A card's
 * linked heading casts an `::after` overlay across the whole card, so it — not
 * the read-more link underneath it — receives the pointer. Styling only
 * `.linea-quiet-link a:hover` would compile fine and never once fire.
 */
.linea-card:hover .linea-quiet-link a,
.linea-quiet-link a:hover,
.linea-quiet-link a:focus-visible {
	border-color: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--contrast);
}

/* Buttons: theme.json owns fill/text; this owns geometry only. */
.wp-block-button__link {
	display: inline-flex;
	min-height: 50px;
	align-items: center;
	justify-content: center;
	transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.wp-block-button.is-style-outline > .wp-block-button__link {
	background-color: transparent;
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--contrast);
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover {
	background-color: var(--wp--preset--color--contrast);
	border-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--white);
}

/* --------------------------------------------------------------------------
   3. Section head (title left, optional link right)
   -------------------------------------------------------------------------- */

.linea-section__head {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: 28px;
	align-items: end;
	margin-bottom: 38px;
}

.linea-section__head > * {
	margin-block-start: 0 !important;
}

/*
 * Section headings are capped for readability, but a max-width inside a
 * constrained layout gets `margin-inline: auto` from core and drifts to the
 * middle — leaving the heading indented while the grid below starts at the
 * gutter. Pin it left so every section shares one left edge.
 */
/* The section owns the measure; this only caps the line length. Core still
   centres a capped child, so the margins are pinned back to the gutter. */
.linea-section__head-copy {
	max-width: 980px;
	margin-left: 0 !important;
	margin-right: 0 !important;
}

.linea-section__head-copy > * {
	margin-block-start: 0;
}

/* The margin reset above is deliberate; the gaps between heading and copy,
   and between consecutive paragraphs, are not. */
.linea-section__head-copy > .wp-block-heading + p {
	max-width: 720px;
	margin-top: 22px !important;
}

.linea-section__head-copy > p + p {
	max-width: 720px;
	margin-top: 16px !important;
}

/*
 * Copy set to the heading's measure rather than a reading measure. Under a
 * two-line heading the narrower default reads as a second, misaligned column;
 * matching the widths costs a few characters per line, which the slightly
 * larger size buys back.
 */
.linea-section__head-copy--wide {
	max-width: 900px;
}

/*
 * Capped below the `huge` preset so the heading lands on two lines rather than
 * three. At the preset's 70px ceiling this heading needs ~1650px of ink, which
 * a 900px measure can only take in three lines; 62px brings it to ~1470px, or
 * two balanced lines. Widening the column instead would push the copy under it
 * past a readable line length.
 */
.linea-section__head-copy--wide > .wp-block-heading {
	font-size: clamp(38px, 4.2vw, 62px);
}

.linea-section__head-copy--wide > .wp-block-heading + p,
.linea-section__head-copy--wide > p + p {
	max-width: none;
	font-size: 18px;
	line-height: 1.62;
}

/* --------------------------------------------------------------------------
   4. Card collections
   -------------------------------------------------------------------------- */

.linea-cards {
	display: grid;
	gap: var(--linea-card-gap);
	align-items: stretch;
}

.linea-cards > * {
	margin-block-start: 0 !important;
}

.linea-cards--4 {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

.linea-cards--3 {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

.linea-cards--2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: clamp(18px, 2.2vw, 34px);
}

.linea-card {
	position: relative;
	display: flex;
	flex-direction: column;
}

.linea-card > * {
	margin-block-start: 0 !important;
}

.linea-card__media {
	position: relative;
	aspect-ratio: 1 / 1.06;
	overflow: hidden;
	background: var(--wp--preset--color--surface-warm);
}

.linea-card__media .wp-block-image,
.linea-card__media figure {
	margin: 0;
	height: 100%;
}

.linea-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.45s ease;
}

.linea-card:hover .linea-card__media img {
	transform: scale(1.025);
}

.linea-card__tag {
	position: absolute;
	top: 14px;
	left: 14px;
	z-index: 2;
	margin: 0;
	padding: 7px 10px;
	background: rgba(246, 243, 237, 0.94);
	color: var(--wp--preset--color--contrast);
	font-size: 12px;
	font-weight: 600;
	line-height: 1.2;
}

.linea-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: 20px 0 0;
}

.linea-card__body > * {
	margin-block-start: 0 !important;
}

.linea-card__body :where(h2, h3, h4) {
	margin: 0;
	font-size: clamp(20px, 1.7vw, 27px);
	line-height: 1.14;
	letter-spacing: -0.035em;
	font-weight: 500;
}

/* One click target for the whole card, without wrapping it in an anchor. */
.linea-card__body :where(h2, h3, h4) a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

/* These beat the blanket `margin-block-start: 0 !important` reset above, which
   exists for grid children and would otherwise flatten the card's rhythm. */
.linea-card__body p {
	margin: 14px 0 0 !important;
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	line-height: 1.65;
}

.linea-card__body :where(h2, h3, h4) + p {
	margin-top: 16px !important;
}

/* Descriptions differ in length, so the read-more is pinned to the bottom of
   the card. Every "Lue lisää" in a row then sits on one line. */
.linea-card__body .linea-quiet-link {
	margin-top: auto !important;
	padding-top: 22px;
}

/* --------------------------------------------------------------------------
   5. Feature pair (image over a filled body)
   -------------------------------------------------------------------------- */

.linea-feature {
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--surface-warm);
}

.linea-feature > * {
	margin-block-start: 0 !important;
}

.linea-feature__media {
	aspect-ratio: 16 / 10;
	overflow: hidden;
}

.linea-feature__media .wp-block-image,
.linea-feature__media figure {
	margin: 0;
	height: 100%;
}

.linea-feature__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.5s ease;
}

.linea-feature:hover .linea-feature__media img {
	transform: scale(1.018);
}

.linea-feature__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: clamp(28px, 3vw, 44px);
}

.linea-feature__body > * {
	margin-block-start: 0 !important;
}

.linea-feature__body :where(h2, h3, h4) {
	margin: 0 0 22px;
	font-size: clamp(30px, 3vw, 45px);
	line-height: 1.06;
	letter-spacing: -0.045em;
}

.linea-feature__body .is-style-dashed {
	margin: 0 0 28px;
}

.is-style-dashed {
	display: grid;
	gap: 7px;
	padding: 0;
	list-style: none;
	color: var(--wp--preset--color--muted);
	font-size: 15px;
}

.is-style-dashed li::before {
	content: "\2013\00a0";
	color: var(--wp--preset--color--accent-dark);
}

.linea-feature__body .linea-arrow-link {
	margin-top: auto;
}

/* --------------------------------------------------------------------------
   6. Split layouts
   -------------------------------------------------------------------------- */

.linea-split {
	display: grid;
	gap: clamp(50px, 8vw, 120px);
	align-items: center;
}

.linea-split > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

.linea-split--copy-first {
	grid-template-columns: 1.05fr 0.95fr;
}

.linea-split--even {
	grid-template-columns: 1fr 1fr;
}

.linea-split--narrow-first {
	grid-template-columns: 0.78fr 1.22fr;
	align-items: start;
}

/* Media beside a list: near-even columns and a tighter gutter than the
   editorial splits, so the picture carries its own weight instead of reading
   as a thumbnail next to a wall of text. */
.linea-split--media-narrow {
	grid-template-columns: 0.95fr 1.05fr;
	gap: clamp(32px, 3.6vw, 60px);
	/* Centred, not top-aligned: the picture and the grid beside it are close to
	   the same height, so whichever is shorter should sit against the other's
	   middle rather than leaving all its slack at the bottom. */
	align-items: center;
}

/* Square, not the 4:5 portrait the editorial splits use: this column is wide
   and its list is short, and a portrait crop here would tower over it. */
.linea-split--media-narrow > .linea-split__media {
	aspect-ratio: 1 / 1;
}

/*
 * A picture that stays while a long column scrolls past it. Same recipe as the
 * sticky heading column: content-height box inside a full-height grid area.
 * The max-height keeps it inside the viewport on short screens, where a sticky
 * element taller than the window can never finish scrolling.
 */
.linea-split--sticky-media > .linea-split__media {
	position: sticky;
	top: calc(var(--linea-header-h) + 44px);
	align-self: start;
	max-height: calc(100vh - var(--linea-header-h) - 88px);
}

.linea-split__media {
	aspect-ratio: 4 / 5;
	overflow: hidden;
}

.linea-split__media .wp-block-image,
.linea-split__media figure {
	margin: 0;
	height: 100%;
}

.linea-split__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.linea-split__content > * {
	margin-block-start: 0;
}

.linea-split__content > * + * {
	margin-block-start: 20px;
}

/*
 * Editorial opener: a hairline separates the section heading from the
 * lead-plus-body pair, so the page reads as an article rather than a stack of
 * loose paragraphs.
 */
.linea-editorial {
	margin-top: clamp(44px, 6vw, 78px) !important;
	padding-top: 34px;
	border-top: 1px solid var(--linea-line);
}

.linea-editorial > .is-style-lead {
	max-width: 480px;
	font-size: clamp(21px, 2vw, 28px);
	line-height: 1.48;
	letter-spacing: -0.025em;
}

.linea-editorial .linea-split__content > * + * {
	margin-block-start: 24px;
}

.linea-editorial .linea-copy {
	max-width: 720px;
}

.has-dark-background-color .linea-editorial,
.has-contrast-background-color .linea-editorial {
	border-top-color: var(--linea-line-on-dark);
}

/* Fact pair under a dark split ------------------------------------------- */

/* Hairlines default to the light-band colour and invert on dark, the same way
   `.linea-faq` does — this pair is used on both now. */
.linea-facts {
	display: grid;
	grid-template-columns: 1fr 1fr;
	margin-top: 42px !important;
	border-top: 1px solid var(--linea-line);
}

.linea-facts > * {
	margin-block-start: 0 !important;
}

.linea-fact {
	padding: 24px 24px 0 0;
	border-right: 1px solid var(--linea-line);
}

.has-dark-background-color .linea-facts,
.has-contrast-background-color .linea-facts,
.has-dark-background-color .linea-fact,
.has-contrast-background-color .linea-fact {
	border-color: var(--linea-line-on-dark);
}

.linea-fact:last-child {
	padding-left: 24px;
	border-right: 0;
}

.linea-fact > * {
	margin-block-start: 0 !important;
}

/* Text follows the same rule as the hairlines: light-band colours by default,
   inverted on a dark band. */
.linea-fact :where(h3, h4, h5, p:first-child) strong,
.linea-fact__title {
	display: block;
	color: var(--wp--preset--color--contrast);
	font-size: 22px;
	font-weight: 500;
	letter-spacing: -0.03em;
	line-height: 1.2;
}

.has-dark-background-color .linea-fact :where(h3, h4, h5, p:first-child) strong,
.has-contrast-background-color .linea-fact :where(h3, h4, h5, p:first-child) strong,
.has-dark-background-color .linea-fact__title,
.has-contrast-background-color .linea-fact__title {
	color: var(--wp--preset--color--on-dark);
}

.linea-fact p:last-child {
	margin-top: 7px !important;
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	line-height: 1.55;
}

.has-dark-background-color .linea-fact p:last-child,
.has-contrast-background-color .linea-fact p:last-child {
	color: rgba(255, 255, 255, 0.66);
}

/* --------------------------------------------------------------------------
   7. Project / reference grid
   -------------------------------------------------------------------------- */

.linea-projects {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--linea-card-gap);
	align-items: stretch;
}

.linea-projects > * {
	margin-block-start: 0 !important;
}

.linea-project {
	position: relative;
	display: flex;
	flex-direction: column;
}

.linea-project > * {
	margin-block-start: 0 !important;
}

.linea-project__media {
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--wp--preset--color--surface-warm);
}

.linea-project__media .wp-block-image,
.linea-project__media figure {
	margin: 0;
	height: 100%;
}

.linea-project__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.45s ease;
}

.linea-project:hover .linea-project__media img {
	transform: scale(1.025);
}

.linea-project__body {
	padding-top: 16px;
}

.linea-project__body > * {
	margin-block-start: 0 !important;
}

.linea-project__meta {
	margin: 0 0 8px !important;
	color: var(--wp--preset--color--muted);
	font-size: 13px;
	line-height: 1.4;
}

.linea-project__body :where(h2, h3, h4) {
	margin: 0;
	font-size: 21px;
	line-height: 1.25;
	letter-spacing: -0.025em;
}

.linea-project__body :where(h2, h3, h4) a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.linea-project__body .linea-arrow-link {
	margin-top: 18px !important;
}

/* --------------------------------------------------------------------------
   8. Quote panel
   -------------------------------------------------------------------------- */

.linea-quote-panel {
	display: grid;
	grid-template-columns: 0.8fr 1.2fr;
	gap: clamp(40px, 7vw, 110px);
	padding: clamp(44px, 6vw, 84px);
	background: var(--wp--preset--color--surface);
}

.linea-quote-panel > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

.linea-quote-panel__col > * {
	margin-block-start: 0;
}

.linea-stat {
	margin: 0;
	font-size: clamp(42px, 5vw, 72px);
	line-height: 1;
	letter-spacing: -0.05em;
	font-weight: 500;
}

.linea-stars {
	margin: 12px 0 0;
	letter-spacing: 4px;
	line-height: 1;
	color: var(--wp--preset--color--highlight);
}

.linea-quote-panel blockquote,
.linea-quote {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: clamp(25px, 3vw, 42px);
	line-height: 1.2;
	letter-spacing: -0.04em;
	font-weight: 450;
}

.linea-quote-panel blockquote p {
	font-size: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	font-weight: inherit;
	margin: 0;
}

/*
 * A caption under a stat. Not to be confused with `.linea-notes__item`, the
 * entry in the "Hyvä tietää" grid further down — that one was briefly called
 * `.linea-note` too and silently gave this paragraph 56px of padding and a
 * hairline it never asked for.
 */
.linea-note {
	margin: 22px 0 0;
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	line-height: 1.5;
}

/* --------------------------------------------------------------------------
   9. Numbered process list
   -------------------------------------------------------------------------- */

.linea-steps {
	margin: 32px 0 0 !important;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--linea-line);
	counter-reset: linea-step;
}

.linea-steps li {
	display: grid;
	grid-template-columns: 30px 1fr;
	gap: 14px;
	padding: 17px 0;
	border-bottom: 1px solid var(--linea-line);
	font-size: 15px;
	line-height: 1.5;
	counter-increment: linea-step;
}

.linea-steps li::before {
	content: counter(linea-step) ".";
	color: var(--wp--preset--color--accent-dark);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   10. FAQ
   -------------------------------------------------------------------------- */

/*
 * Rows, not a bare list of hairlines. Each question is a full-width target with
 * a ringed +/- control on the right; hovering tints the row and opening it
 * fills the control and lifts the answer onto a surface. The heading column
 * keeps its own distance so the questions never crowd it.
 */
.linea-faq {
	border-top: 1px solid var(--linea-line);
}

.linea-faq > * {
	margin-block-start: 0 !important;
}

.linea-faq .wp-block-details,
.is-style-divided {
	border-bottom: 1px solid var(--linea-line);
	padding: 0;
	background: none;
	transition: background-color 0.2s ease;
}

.linea-faq summary,
.is-style-divided > summary {
	position: relative;
	list-style: none;
	cursor: pointer;
	display: flex;
	align-items: center;
	gap: 24px;
	padding: 26px 24px 26px 4px;
	font-size: clamp(17px, 1.4vw, 20px);
	line-height: 1.35;
	letter-spacing: -0.02em;
	font-weight: 500;
	transition: color 0.2s ease;
}

.linea-faq summary::-webkit-details-marker,
.is-style-divided > summary::-webkit-details-marker {
	display: none;
}

/* The control: a ringed circle holding a + that becomes a − when open. */
.linea-faq summary::after,
.is-style-divided > summary::after {
	content: "";
	flex: 0 0 auto;
	margin-left: auto;
	width: 34px;
	height: 34px;
	border: 1px solid var(--linea-line);
	border-radius: 50%;
	background:
		linear-gradient(currentColor, currentColor) center / 12px 1.5px no-repeat,
		linear-gradient(currentColor, currentColor) center / 1.5px 12px no-repeat;
	transition: transform 0.25s ease, background-color 0.2s ease, border-color 0.2s ease;
}

.linea-faq details[open] > summary::after,
.is-style-divided[open] > summary::after {
	/* Hide the vertical bar to turn the + into a −, and spin on the way. */
	background:
		linear-gradient(currentColor, currentColor) center / 12px 1.5px no-repeat;
	transform: rotate(180deg);
	border-color: currentColor;
}

.linea-faq summary:hover,
.is-style-divided > summary:hover {
	color: var(--wp--preset--color--accent-dark);
}

.linea-faq summary:hover::after,
.is-style-divided > summary:hover::after {
	border-color: currentColor;
}

/*
 * The padding matters as much as the tint. Without it the answer's bottom
 * margin collapses straight through the padding-free `details` box, so the
 * open panel closed a few pixels under the last line of text.
 *
 * 24px against the summary's 26px top padding, not 26px: the answer is set at
 * 16/28 and the question at 20/27, so the answer carries ~2.5px more half-
 * leading below its last line. Matching the numbers would leave the panel
 * looking bottom-heavy; matching the ink is what reads as even.
 */
.linea-faq details[open],
.is-style-divided[open] {
	background-color: var(--wp--preset--color--base);
	padding-bottom: 24px;
}

.linea-faq details[open] > summary,
.is-style-divided[open] > summary {
	padding-left: 24px;
	padding-bottom: 14px;
}

.linea-faq details p,
.is-style-divided > :not(summary) {
	max-width: 720px;
	margin: 0 24px 26px;
	color: var(--wp--preset--color--muted);
	font-size: 16px;
	line-height: 1.75;
}

/* On a white band the open row needs a warmer tint to read as "open". */
.has-white-background-color .linea-faq details[open] {
	background-color: var(--wp--preset--color--paper);
}

/* Dark bands: same behaviour, inverted hairlines. */
.has-dark-background-color .linea-faq,
.has-dark-background-color .linea-faq .wp-block-details {
	border-color: var(--linea-line-on-dark);
}

.has-dark-background-color .linea-faq summary::after {
	border-color: var(--linea-line-on-dark);
}

.has-dark-background-color .linea-faq details[open] {
	background-color: rgba(255, 255, 255, 0.05);
}

/* The heading column keeps its distance from the questions. It is also a touch
   wider than the other narrow columns, to carry the larger heading. */
.linea-faq-split {
	grid-template-columns: 0.85fr 1.15fr;
	gap: clamp(56px, 9vw, 140px);
}

/*
 * A section heading demoted into a narrow side column.
 *
 * The pages are in Finnish, where a single compound ("Kylpyhuoneremontti",
 * "vanhannäköinen") is wider than this column at the full section-heading size
 * — it overflowed across the content beside it. A smaller size for this
 * placement, plus hyphenation as the safety net at the viewports in between.
 *
 * Opt in with `--heading-column`; a plain `--narrow-first` split whose first
 * column is copy rather than a heading is unaffected.
 */
/*
 * The heading column is much shorter than the content beside it, so it would
 * otherwise leave a column of dead space. Sticking it keeps the subject on
 * screen while the reader works down the cards, and gives the emptiness a job.
 * `align-self: start` is what makes this work: the box stays content-height
 * while its grid area spans the full row, which is the room sticky travels in.
 */
.linea-split--heading-column > :first-child,
.linea-faq-split > :first-child {
	position: sticky;
	top: calc(var(--linea-header-h) + 44px);
	align-self: start;
}

.linea-split--heading-column > :first-child :where(h2),
.linea-faq-split > :first-child :where(h2) {
	font-size: clamp(32px, 3.6vw, 52px);
	line-height: 1.06;
	hyphens: auto;
	overflow-wrap: break-word;
}

@media (max-width: 1080px) {
	.linea-faq-split {
		grid-template-columns: 1fr;
		gap: 40px;
	}
}

/* --------------------------------------------------------------------------
   11. Link strip (horizontal quick nav)
   -------------------------------------------------------------------------- */

.linea-link-strip {
	border-top: 1px solid var(--linea-line);
	border-bottom: 1px solid var(--linea-line);
	padding-block: 0 !important;
}

.linea-link-strip__inner {
	display: flex;
	gap: 0;
	overflow-x: auto;
	scrollbar-width: none;
}

.linea-link-strip__inner::-webkit-scrollbar {
	display: none;
}

.linea-link-strip__inner > * {
	margin-block-start: 0 !important;
	flex: 0 0 auto;
	padding: 20px 30px;
	border-right: 1px solid var(--linea-line);
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	white-space: nowrap;
	transition: color 0.2s ease;
}

.linea-link-strip__inner > *:first-child {
	padding-left: 0;
}

.linea-link-strip__inner > *:hover {
	color: var(--wp--preset--color--contrast);
}

/* --------------------------------------------------------------------------
   12. Cover hero
   -------------------------------------------------------------------------- */

.linea-hero.wp-block-cover {
	min-height: 100svh;
	align-items: flex-end;
	padding: 0;
	color: var(--wp--preset--color--on-dark);
}

/*
 * A hero that is the whole page. Nothing follows it, so a full viewport would
 * leave the reader looking for content that does not exist; this height ends
 * the page on its own terms while keeping the hero's proportions.
 */
.linea-hero--compact.wp-block-cover {
	min-height: clamp(520px, 76svh, 760px);
}

.linea-hero--compact .linea-hero__inner {
	padding-top: clamp(120px, 14vh, 180px);
}

/* Two scrims: vertical for legibility at the bottom, horizontal for the copy. */
.linea-hero.wp-block-cover::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: linear-gradient(
		180deg,
		rgba(16, 18, 15, 0.22) 0%,
		rgba(16, 18, 15, 0.1) 30%,
		rgba(16, 18, 15, 0.36) 60%,
		rgba(16, 18, 15, 0.86) 100%
	);
}

.linea-hero.wp-block-cover::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	background: linear-gradient(
		90deg,
		rgba(18, 20, 17, 0.8) 0%,
		rgba(18, 20, 17, 0.62) 32%,
		rgba(18, 20, 17, 0.25) 62%,
		rgba(18, 20, 17, 0) 88%
	);
}

/*
 * `antialiased` smoothing visibly thins light-on-dark text. The hero is the one
 * place the site puts white type on photography, so it opts back out.
 */
.linea-hero,
.linea-hero * {
	-webkit-font-smoothing: auto;
	-moz-osx-font-smoothing: auto;
}

.linea-hero .wp-block-cover__image-background {
	object-position: center 54%;
}

.linea-hero .wp-block-cover__inner-container {
	position: relative;
	z-index: 2 !important;
	width: 100%;
}

.linea-hero__inner {
	position: relative;
	z-index: 2;
	width: 100%;
	padding-inline: max(var(--linea-gutter), calc((100% - var(--linea-wrap)) / 2));
	padding-top: clamp(150px, 18vh, 230px);
	/* The hero is `min-height: 100svh` with its content bottom-aligned, so the
	   bottom padding is what lifts the block off the fold. */
	padding-bottom: clamp(72px, 11vh, 132px);
}

.linea-hero__inner > * {
	margin-block-start: 0 !important;
}

.linea-hero__content {
	max-width: 920px;
}

.linea-hero__content > * {
	margin-block-start: 0;
}

.linea-hero__trust {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 22px;
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.4;
	text-shadow: 0 1px 2px rgba(16, 18, 15, 0.45);
}

.linea-hero__stars {
	letter-spacing: 2px;
	font-size: 13px;
	color: var(--wp--preset--color--highlight);
}

/*
 * Lighter than the 500 the other headings use. At the display size the hero
 * runs to, 500 reads as heavy and slightly dated; 400 with the same tight
 * tracking keeps the scale and loses the weight. Inter is variable (100–900),
 * so this is a real weight, not a synthesised one.
 */
.linea-hero h1 {
	max-width: 900px;
	margin: 0;
	color: var(--wp--preset--color--on-dark);
	font-weight: 400;
}

/*
 * 400, the same weight as body copy everywhere else, rather than the 450 it
 * carried to hold up against photography. Kept at 400 and no lighter: this line
 * sits on an image behind a scrim, and below body weight the shadow starts
 * doing more work than the letterforms.
 */
.linea-hero__intro {
	max-width: 720px;
	margin: 26px 0 0;
	color: #fff;
	font-size: clamp(17px, 1.35vw, 20px);
	line-height: 1.6;
	font-weight: 400;
	text-shadow: 0 1px 2px rgba(16, 18, 15, 0.6);
}

.linea-hero h1 {
	text-shadow: 0 1px 3px rgba(16, 18, 15, 0.5);
}

.linea-hero .wp-block-buttons {
	margin-top: 30px;
	gap: 10px;
}

.linea-hero .wp-block-button__link {
	border-color: var(--wp--preset--color--white);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--contrast);
}

.linea-hero .wp-block-button__link:hover {
	border-color: var(--wp--preset--color--surface-warm);
	background-color: var(--wp--preset--color--surface-warm);
	color: var(--wp--preset--color--contrast);
}

.linea-hero .wp-block-button.is-style-outline > .wp-block-button__link {
	border-color: rgba(255, 255, 255, 0.72);
	background-color: rgba(255, 255, 255, 0.06);
	color: var(--wp--preset--color--on-dark);
}

.linea-hero .wp-block-button.is-style-outline > .wp-block-button__link:hover {
	border-color: var(--wp--preset--color--white);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--contrast);
}

.linea-hero__contacts {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	margin: 34px 0 0;
	color: #fff;
	font-size: 14px;
	font-weight: 500;
	line-height: 1.4;
	text-shadow: 0 1px 3px rgba(16, 18, 15, 0.5);
}

.linea-hero__contacts a {
	border-bottom: 1px solid rgba(255, 255, 255, 0.55);
	padding-bottom: 3px;
	transition: color 0.2s ease, border-color 0.2s ease;
}

.linea-hero__contacts a:hover {
	color: var(--wp--preset--color--highlight);
	border-bottom-color: var(--wp--preset--color--highlight);
}

/* --------------------------------------------------------------------------
   13. Header
   -------------------------------------------------------------------------- */

.linea-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	min-height: var(--linea-header-h);
	padding: 10px max(var(--linea-gutter), calc((100% - var(--linea-wrap)) / 2));
	color: var(--wp--preset--color--on-dark);
	/* Solid is the safe default: without JS the header is still legible. */
	background-color: var(--wp--preset--color--dark);
	box-shadow: 0 1px 0 0 rgba(29, 29, 31, 0.1);
	transition: transform 0.4s ease, background-color 0.3s ease, box-shadow 0.3s ease;
}

/*
 * Never lazily rendered: `content-visibility: auto` (WP Rocket adds it to
 * elements it thinks are below the fold) clips the header to its own box and
 * cuts the navigation dropdowns off at the header's bottom edge.
 */
.linea-header,
.linea-lp-header,
.linea-lp-callbar {
	content-visibility: visible !important;
}

/* JS adds this only while the header floats over a full-bleed hero. */
.linea-header.is-transparent {
	background-color: transparent;
	box-shadow: none;
}

.linea-header.is-hidden {
	transform: translateY(-100%);
}

.linea-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24px;
	width: 100%;
}

.linea-header__inner > * {
	margin-block-start: 0 !important;
}

.linea-header__brand {
	display: flex;
	align-items: center;
	gap: 10px;
}

.linea-header__brand > * {
	margin-block-start: 0 !important;
}

.linea-header .wp-block-site-logo img {
	width: 33px;
	height: auto;
}

.linea-header .wp-block-site-title a,
.linea-header .wp-block-site-title {
	color: var(--wp--preset--color--on-dark);
	font-size: 20px;
	font-weight: 500;
	letter-spacing: -0.02em;
}

.linea-header__nav {
	display: flex;
	align-items: center;
	gap: 22px;
}

.linea-header__nav > * {
	margin-block-start: 0 !important;
}

.linea-header .wp-block-navigation {
	--wp--style--block-gap: 0;
	font-size: 14px;
	font-weight: 500;
}

.linea-header .wp-block-navigation .wp-block-navigation-item__content {
	color: var(--wp--preset--color--on-dark);
	padding: 8px 12px;
	border-radius: 999px;
	transition: background-color 0.2s ease;
}

.linea-header .wp-block-navigation > .wp-block-navigation__container > .wp-block-navigation-item:hover {
	background-color: rgba(255, 255, 255, 0.12);
	border-radius: 999px;
}

.linea-header .wp-block-navigation__submenu-icon {
	background-color: transparent;
	color: currentColor;
}

/* Desktop dropdown — a real card, not the inherited overlay colours. */
@media (min-width: 782px) {
	.linea-header .wp-block-navigation__submenu-container {
		background-color: var(--wp--preset--color--white) !important;
		color: var(--wp--preset--color--contrast) !important;
		border: 1px solid var(--linea-line) !important;
		border-radius: 14px;
		box-shadow: 0 14px 38px rgba(30, 33, 29, 0.16);
		padding: 6px !important;
		min-width: 268px;
		gap: 1px !important;
		margin-top: 8px;
	}

	/* Bridge the offset so :hover does not drop between trigger and panel. */
	.linea-header .wp-block-navigation__submenu-container::before {
		content: "";
		position: absolute;
		left: 0;
		right: 0;
		top: -10px;
		height: 10px;
	}

	.linea-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		color: var(--wp--preset--color--contrast) !important;
		padding: 10px 14px !important;
		border-radius: 9px;
		white-space: nowrap;
		font-weight: 500;
	}

	.linea-header .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
		background-color: rgba(80, 89, 74, 0.1);
		color: var(--wp--preset--color--accent-dark) !important;
	}
}

/*
 * A data slot, never rendered. The drawer is built in JS from the site's own
 * content, so the CTA and contact links live here rather than in theme code.
 */
.linea-header__drawer-slot {
	display: none;
}

/* Header call-to-action ---------------------------------------------------- */

.linea-header__cta .wp-block-button__link {
	min-height: 42px;
	padding: 11px 20px;
	border-color: var(--wp--preset--color--white);
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--contrast);
	border-radius: 999px;
}

.linea-header__cta .wp-block-button__link:hover {
	border-color: var(--wp--preset--color--surface-warm);
	background-color: var(--wp--preset--color--surface-warm);
	color: var(--wp--preset--color--contrast);
}

.linea-header__toggle {
	display: none;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.4);
	border-radius: 999px;
	background: transparent;
	color: var(--wp--preset--color--on-dark);
	cursor: pointer;
}

.linea-header__toggle svg {
	width: 20px;
	height: 20px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
	stroke-linecap: round;
}

/* --------------------------------------------------------------------------
   13b. Quick actions rail
   -------------------------------------------------------------------------- */

/*
 * The two or three things a visitor wants at any scroll position: call, email,
 * jump to the form. Fixed to the right edge, vertically centred, and it steps
 * out of the way once the form itself is on screen. Built in JS from the
 * header's site-owned contact slot, so no number lives in theme code.
 */
.linea-quick-actions {
	position: fixed;
	/* Tight to the edge, but never flush against it. */
	right: clamp(8px, 0.7vw, 11px);
	top: 50%;
	z-index: 9998;
	display: grid;
	gap: 10px;
	transform: translateY(-50%);
	transition: opacity 0.3s ease, transform 0.3s ease;
}

.linea-quick-actions.is-hidden {
	opacity: 0;
	visibility: hidden;
	transform: translateY(-50%) translateX(16px);
}

.linea-quick-actions__item {
	position: relative;
	display: grid;
	place-items: center;
	width: 52px;
	height: 52px;
	border-radius: 50%;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
	box-shadow: 0 6px 20px rgba(30, 33, 29, 0.22);
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.linea-quick-actions__item:hover,
.linea-quick-actions__item:focus-visible {
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--dark);
	transform: translateX(-3px);
}

/*
 * Solid glyphs, not outlines. At 21px inside a filled circle a hairline stroke
 * reads as noise; a solid shape survives the small size and the dark disc.
 */
.linea-quick-actions__item svg {
	width: 21px;
	height: 21px;
	fill: currentColor;
	stroke: none;
}

/* The label is the accessible name and a hover tooltip, not decoration. */
.linea-quick-actions__label {
	position: absolute;
	right: calc(100% + 12px);
	white-space: nowrap;
	padding: 8px 12px;
	border-radius: 4px;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
	font-size: 13px;
	font-weight: 500;
	line-height: 1;
	opacity: 0;
	pointer-events: none;
	transform: translateX(6px);
	transition: opacity 0.2s ease, transform 0.2s ease;
}

.linea-quick-actions__item:hover .linea-quick-actions__label,
.linea-quick-actions__item:focus-visible .linea-quick-actions__label {
	opacity: 1;
	transform: translateX(0);
}

@media (max-width: 760px) {
	/*
	 * Vertically centred, the rail sits in the middle of a 390px screen and
	 * lands on top of the running text — headings in the hero and in each
	 * band ran under the buttons. There is no room for a gutter beside a
	 * full-width column, so on a phone the rail becomes what a floating
	 * action group normally is: a row in the bottom corner.
	 */
	.linea-quick-actions {
		top: auto;
		bottom: 14px;
		grid-auto-flow: column;
		transform: none;
	}

	.linea-quick-actions.is-hidden {
		transform: translateY(16px);
	}

	.linea-quick-actions__item {
		width: 46px;
		height: 46px;
	}

	.linea-quick-actions__item svg {
		width: 19px;
		height: 19px;
	}

	/* No hover on touch, so the tooltip would only ever get in the way. */
	.linea-quick-actions__label {
		display: none;
	}
}

/* The drawer covers the viewport; the rail must not float over it. */
body.linea-drawer-open .linea-quick-actions {
	opacity: 0;
	visibility: hidden;
}

/* --------------------------------------------------------------------------
   14. Mobile drawer
   -------------------------------------------------------------------------- */

.linea-drawer {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
	transform: translateY(-100%);
	visibility: hidden;
	transition: transform 0.35s ease, visibility 0.35s;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.linea-drawer.is-open {
	transform: translateY(0);
	visibility: visible;
}

.linea-drawer__top {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	min-height: var(--linea-header-h);
	padding: 10px max(var(--linea-gutter), calc((100% - var(--linea-wrap)) / 2));
	border-bottom: 1px solid var(--linea-line-on-dark);
}

.linea-drawer__brand {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 20px;
	font-weight: 500;
	letter-spacing: -0.02em;
}

.linea-drawer__brand img {
	width: 33px;
	height: auto;
}

.linea-drawer__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.4);
	border-radius: 999px;
	background: transparent;
	color: var(--wp--preset--color--on-dark);
	cursor: pointer;
}

.linea-drawer__close svg {
	width: 18px;
	height: 18px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
	stroke-linecap: round;
}

.linea-drawer__nav {
	flex: 1;
	padding: 8px var(--linea-gutter) 0;
}

.linea-drawer__nav ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.linea-drawer__nav > ul > li {
	border-bottom: 1px solid var(--linea-line-on-dark);
}

.linea-drawer__row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
}

.linea-drawer__nav a {
	display: block;
	flex: 1;
	padding: 18px 0;
	color: var(--wp--preset--color--on-dark);
	font-size: 19px;
	font-weight: 500;
	letter-spacing: -0.02em;
}

.linea-drawer__sub-toggle {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--on-dark);
	cursor: pointer;
}

.linea-drawer__sub-toggle svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	transition: transform 0.25s ease;
}

.linea-drawer__sub-toggle[aria-expanded="true"] svg {
	transform: rotate(180deg);
}

.linea-drawer__sub {
	display: none;
	padding: 0 0 14px 14px;
	border-left: 1px solid var(--linea-line-on-dark);
	margin-bottom: 6px;
}

.linea-drawer__sub.is-open {
	display: block;
}

.linea-drawer__sub a {
	padding: 10px 0;
	color: rgba(255, 255, 255, 0.82);
	font-size: 16px;
	font-weight: 400;
}

.linea-drawer__foot {
	display: grid;
	gap: 14px;
	padding: 26px var(--linea-gutter) 34px;
	border-top: 1px solid var(--linea-line-on-dark);
}

.linea-drawer__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 52px;
	padding: 0 24px;
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--contrast);
	font-size: 15px;
	font-weight: 600;
}

.linea-drawer__contacts {
	display: grid;
	gap: 8px;
	color: rgba(255, 255, 255, 0.82);
	font-size: 15px;
}

/*
 * The lock has to go on the element that actually scrolls. `html` is the
 * scrolling element here, so `overflow: hidden` on `body` alone left the page
 * scrolling merrily behind the open drawer.
 */
html:has(> body.linea-drawer-open),
body.linea-drawer-open {
	overflow: hidden;
}

/* --------------------------------------------------------------------------
   14b. Scope cards, process grid, price tiles, duration table, local links
   -------------------------------------------------------------------------- */

/* Scope cards -------------------------------------------------------------*/

/*
 * Deliberately light: a hairline, an icon, a title and a line of text. No fill,
 * no border box. Six of these read as a list of capabilities rather than six
 * competing panels, which is what a filled card grid turns into at this count.
 */
.linea-scope {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(28px, 3.4vw, 56px) clamp(28px, 3vw, 52px);
	align-items: start;
}

.linea-scope > * {
	margin-block-start: 0 !important;
}

/* Beside a heading column instead of under a section head, six cards need two
   columns rather than three — three would set the text to about 28 characters. */
.linea-scope--two {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.linea-scope-card {
	display: flex;
	flex-direction: column;
	padding-top: 26px;
	border-top: 1px solid var(--linea-line);
}

.linea-scope-card > * {
	margin-block-start: 0 !important;
}

/* The icon and the index share one row, so the eye lands on the icon first. */
.linea-scope-card__top {
	display: flex;
	align-items: center;
	gap: 14px;
	margin: 0 0 22px !important;
	font-size: 13px;
	font-weight: 600;
	line-height: 1;
}

.linea-scope-card__top::before {
	content: "";
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: var(--wp--preset--color--surface-warm) var(--linea-scope-icon, none) center / 24px 24px no-repeat;
}

.linea-scope-card__top .linea-num {
	color: var(--wp--preset--color--accent-dark);
	font-variant-numeric: tabular-nums;
}

.linea-scope-card__top .linea-tag {
	margin-left: auto;
	color: var(--wp--preset--color--muted);
	font-size: 12px;
	font-weight: 400;
}

.linea-scope-card :where(h2, h3, h4) {
	margin: 0 !important;
	font-size: clamp(21px, 1.8vw, 27px);
	line-height: 1.12;
	letter-spacing: -0.035em;
}

.linea-scope-card p:last-child {
	margin: 12px 0 0 !important;
	color: var(--wp--preset--color--muted);
	font-size: 15px;
	line-height: 1.65;
}

/*
 * Icon per card, set by a modifier the page content carries. Both the grid
 * card and the stacked list item read the same `--linea-scope-icon`, so an
 * editor moving content between the two layouts keeps its icon.
 */
.linea-scope-card--wall, .linea-scope-item--wall { --linea-scope-icon: url("../icons/scope/wall.svg"); }
.linea-scope-card--floor, .linea-scope-item--floor { --linea-scope-icon: url("../icons/scope/floor.svg"); }
.linea-scope-card--ceiling, .linea-scope-item--ceiling { --linea-scope-icon: url("../icons/scope/ceiling.svg"); }
.linea-scope-card--trim, .linea-scope-item--trim { --linea-scope-icon: url("../icons/scope/trim.svg"); }
.linea-scope-card--door, .linea-scope-item--door { --linea-scope-icon: url("../icons/scope/door.svg"); }
.linea-scope-card--detail, .linea-scope-item--detail { --linea-scope-icon: url("../icons/scope/detail.svg"); }
.linea-scope-card--brush, .linea-scope-item--brush { --linea-scope-icon: url("../icons/scope/brush.svg"); }
.linea-scope-card--roller, .linea-scope-item--roller { --linea-scope-icon: url("../icons/scope/roller.svg"); }
.linea-scope-card--wallpaper, .linea-scope-item--wallpaper { --linea-scope-icon: url("../icons/scope/wallpaper.svg"); }
.linea-scope-card--sanding, .linea-scope-item--sanding { --linea-scope-icon: url("../icons/scope/sanding.svg"); }
.linea-scope-card--demolition, .linea-scope-item--demolition { --linea-scope-icon: url("../icons/scope/demolition.svg"); }
.linea-scope-card--measure, .linea-scope-item--measure { --linea-scope-icon: url("../icons/scope/measure.svg"); }
.linea-scope-card--shield, .linea-scope-item--shield { --linea-scope-icon: url("../icons/scope/shield.svg"); }
.linea-scope-card--document, .linea-scope-item--document { --linea-scope-icon: url("../icons/scope/document.svg"); }
.linea-scope-card--cabinet, .linea-scope-item--cabinet { --linea-scope-icon: url("../icons/scope/cabinet.svg"); }
.linea-scope-card--deck, .linea-scope-item--deck { --linea-scope-icon: url("../icons/scope/deck.svg"); }

/* Scope list --------------------------------------------------------------*/

/*
 * The same six entries as the card grid, unpacked into a single ruled column
 * so they can sit beside a picture. Icon in its own column spanning the whole
 * entry, then the tag, the title and the line of copy — the eye goes down one
 * edge instead of scanning a grid.
 */
/*
 * Two columns of three, not one of six.
 *
 * Six full-width entries ran far taller than the picture beside them and made
 * the section a scroll in its own right. Paired up, the list matches the
 * picture's height and the whole thing reads as one block.
 *
 * The tag is gone from these entries. Set inline before the title it turned
 * "Luvat" and "Ilmoitukset" into one unreadable phrase, and set above it, it
 * cost a line per entry to repeat what the title already said.
 */
.linea-scope-list {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	column-gap: clamp(22px, 2.4vw, 38px);
	margin-top: clamp(26px, 2.8vw, 36px) !important;
}

/*
 * Icon in its own column spanning the entry, title and description stacked
 * beside it. The rule is on the top edge so the three rows of the grid share
 * one hairline each, which only lines up because grid rows share height.
 */
.linea-scope-item {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	/* A first row at least as tall as the disc, so a one-line title centres
	   against it instead of hanging off its top edge. */
	grid-template-rows: minmax(36px, auto) auto;
	column-gap: clamp(12px, 1.2vw, 16px);
	align-content: start;
	padding: 18px 0 20px;
	border-top: 1px solid var(--linea-line);
}

.linea-scope-item::before {
	content: "";
	grid-column: 1;
	grid-row: 1 / span 2;
	align-self: start;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--wp--preset--color--surface-warm) var(--linea-scope-icon, none) center / 20px 20px no-repeat;
}

.linea-scope-item :where(h2, h3, h4) {
	grid-column: 2;
	grid-row: 1;
	align-self: center;
	margin: 0 !important;
	font-size: clamp(18px, 1.4vw, 20px);
	line-height: 1.2;
	letter-spacing: -0.03em;
}

.linea-scope-item p:last-child {
	grid-column: 2;
	grid-row: 2;
	margin: 7px 0 0 !important;
	color: var(--wp--preset--color--muted);
	font-size: 15px;
	line-height: 1.55;
}

/*
 * The awkward band: the media split still has two columns here, so the list is
 * pairing up inside an already-halved column and its lines fall to about 30
 * characters. Below 1080 the split itself collapses and the list gets the full
 * width back, so two columns are fine again down to 860.
 */
@media (max-width: 1180px) and (min-width: 1081px) {
	.linea-scope-list {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 860px) {
	.linea-scope-list {
		grid-template-columns: 1fr;
	}
}

/* Process cards on a dark band ---------------------------------------------*/

.linea-process {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 22px;
	margin-top: 48px !important;
	align-items: stretch;
}

.linea-process > * {
	margin-block-start: 0 !important;
}

/*
 * The step number sits beside its step, not above it.
 *
 * Stacked, the numeral read as a decoration the eye skipped on its way to the
 * title. Set as a filled disc in the left column, spanning both text rows, it
 * becomes the thing that says "step 4 of 6" while the title says what step 4
 * is — and the card loses about 70px of height it was only using to separate
 * the two.
 */
.linea-process-card {
	position: relative;
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	grid-template-rows: minmax(46px, auto) auto;
	column-gap: clamp(16px, 1.5vw, 22px);
	align-content: start;
	padding: clamp(22px, 2.2vw, 30px);
	border: 1px solid rgba(255, 255, 255, 0.16);
	background: rgba(255, 255, 255, 0.045);
	transition: transform 0.25s ease, background-color 0.25s ease, border-color 0.25s ease;
}

.linea-process-card > * {
	margin-block-start: 0 !important;
}

.linea-process-card:hover {
	transform: translateY(-6px);
	border-color: rgba(255, 255, 255, 0.34);
	background: rgba(255, 255, 255, 0.08);
}

.linea-process-card::after {
	content: "\2192";
	position: absolute;
	top: 50%;
	right: -19px;
	z-index: 2;
	width: 16px;
	display: grid;
	place-items: center;
	color: rgba(255, 255, 255, 0.48);
	font-size: 23px;
	line-height: 1;
	transform: translateY(-50%);
}

.linea-process-card:nth-child(3n)::after,
.linea-process-card:last-child::after {
	display: none;
}

/*
 * Filled highlight, near-black numeral. White on `highlight` measures 2.1:1,
 * which the site's AA commitment does not allow; `contrast` on the same disc
 * measures 8.9:1 and keeps the amber reading as the accent it is.
 */
.linea-process-card__num {
	grid-column: 1;
	grid-row: 1 / span 2;
	align-self: start;
	width: 46px;
	height: 46px;
	margin: 0;
	display: grid;
	place-items: center;
	border: 0;
	border-radius: 50%;
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--contrast) !important;
	font-size: 20px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

.linea-process-card :where(h2, h3, h4) {
	grid-column: 2;
	grid-row: 1;
	align-self: center;
	margin: 0 !important;
	color: var(--wp--preset--color--on-dark);
	font-size: clamp(19px, 1.55vw, 23px);
	line-height: 1.18;
	letter-spacing: -0.03em;
}

.linea-process-card p:last-child {
	grid-column: 2;
	grid-row: 2;
	margin: 12px 0 0 !important;
	color: rgba(255, 255, 255, 0.7);
	font-size: 15px;
	line-height: 1.65;
}

/* Price tiles --------------------------------------------------------------*/

.linea-price {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(16px, 2vw, 28px);
	margin-top: 34px !important;
	align-items: stretch;
}

.linea-price > * {
	margin-block-start: 0 !important;
}

.linea-price-card {
	min-height: 196px;
	display: flex;
	flex-direction: column;
	padding: clamp(22px, 2.4vw, 30px);
	border: 1px solid var(--linea-line);
	background: var(--wp--preset--color--white);
	transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.linea-price-card > * {
	margin-block-start: 0 !important;
}

.linea-price-card:hover {
	transform: translateY(-4px);
	border-color: rgba(80, 89, 74, 0.5);
	box-shadow: 0 18px 42px rgba(30, 33, 29, 0.08);
}

/*
 * Each tier gets a line icon on a tinted disc, kept out of the block markup so
 * the cards stay two plain paragraphs an editor can retype. A CSS mask can only
 * paint one colour per pseudo-element and this needs two, so the icon's stroke
 * colour is baked into the SVG files. The grid is always three tiers, hence
 * nth-child.
 */
.linea-price-card::before {
	content: "";
	display: block;
	flex: 0 0 auto;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--wp--preset--color--surface-warm) var(--linea-tier-icon) center / 34px 34px no-repeat;
}

.linea-price-card:nth-child(1) {
	--linea-tier-icon: url("../icons/tier-1.svg");
}

.linea-price-card:nth-child(2) {
	--linea-tier-icon: url("../icons/tier-2.svg");
}

.linea-price-card:nth-child(3) {
	--linea-tier-icon: url("../icons/tier-3.svg");
}

.linea-price-card__label {
	margin: auto 0 0 !important;
	padding-top: 22px;
	color: var(--wp--preset--color--muted);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.4;
}

.linea-price-card__value {
	margin: 12px 0 0 !important;
	font-size: clamp(31px, 3vw, 42px);
	line-height: 1;
	letter-spacing: -0.035em;
	font-weight: 500;
}

/* Duration table -----------------------------------------------------------*/

.linea-duration {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(14px, 1.6vw, 22px);
	margin-top: 34px !important;
}

.linea-duration > * {
	margin-block-start: 0 !important;
}

/*
 * No `min-height`. The value used to be pushed to the bottom of a 190px box by
 * `margin-top: auto`, which left a hole between the label and the number it
 * labels; the cards are now as tall as their content and the pair reads as one
 * thing. Equal heights still come from the grid's default row stretch.
 */
.linea-duration-card {
	display: flex;
	flex-direction: column;
	padding: clamp(20px, 2.1vw, 26px);
	border: 1px solid var(--linea-line);
	background: var(--wp--preset--color--white);
}

.linea-duration-card > * {
	margin-block-start: 0 !important;
}

.linea-duration-card p:first-child {
	margin: 0 0 0 !important;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--linea-line);
	color: var(--wp--preset--color--muted);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.01em;
	line-height: 1.4;
}

.linea-duration-card__value {
	margin: 14px 0 0 !important;
	font-size: clamp(25px, 2.4vw, 34px);
	line-height: 1.08;
	letter-spacing: -0.04em;
	font-weight: 500;
}

/* Prose block — long-form service copy ------------------------------------ */

/*
 * For pages where the client wants to write more than a card or a list holds:
 * a heading plus real body text at reading width, with its own vertical rhythm.
 * Nothing here is component-specific, so an editor can add headings, lists and
 * paragraphs freely and the result stays typeset.
 */
.linea-prose {
	max-width: var(--linea-reading);
}

.linea-prose > * {
	margin-block-start: 0;
}

.linea-prose > * + * {
	margin-block-start: 1.15em;
}

.linea-prose :where(h2) {
	margin-block-start: 1.9em;
	font-size: clamp(28px, 2.6vw, 40px);
	line-height: 1.1;
	letter-spacing: -0.04em;
}

.linea-prose :where(h3) {
	margin-block-start: 1.7em;
	font-size: clamp(21px, 1.7vw, 26px);
	line-height: 1.2;
	letter-spacing: -0.03em;
}

.linea-prose :where(h2, h3) + * {
	margin-block-start: 0.7em;
}

.linea-prose :where(p, li) {
	color: var(--wp--preset--color--muted);
	font-size: clamp(16px, 1.35vw, 18px);
	line-height: 1.75;
}

.linea-prose :where(p) strong {
	color: var(--wp--preset--color--contrast);
	font-weight: 600;
}

.linea-prose :where(ul, ol) {
	padding-left: 1.1em;
}

.linea-prose :where(li) + li {
	margin-top: 0.5em;
}

.linea-prose :where(blockquote) {
	margin: 1.9em 0;
	padding-left: 28px;
	border-left: 2px solid var(--wp--preset--color--accent-dark);
	color: var(--wp--preset--color--contrast);
	font-size: clamp(19px, 1.7vw, 23px);
	line-height: 1.5;
	letter-spacing: -0.02em;
}

.linea-prose :where(blockquote) p {
	color: inherit;
	font-size: inherit;
	line-height: inherit;
}

/* A two-column variant when the section heading sits beside the prose. */
.linea-prose-split {
	display: grid;
	grid-template-columns: 0.78fr 1.22fr;
	gap: clamp(48px, 7vw, 96px);
	align-items: start;
}

.linea-prose-split > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

@media (max-width: 1080px) {
	.linea-prose-split {
		grid-template-columns: 1fr;
		gap: 36px;
	}
}

/* Band -------------------------------------------------------------------- */

/*
 * A ruled strip closing a section, the full width of the block above it and
 * sharing its column rhythm. Use it when a subject belongs to the section it
 * follows but only has a heading and a couple of paragraphs to its name —
 * enough to say, not enough to earn a band of its own.
 */
.linea-band {
	margin-top: clamp(56px, 6vw, 84px) !important;
	padding-top: clamp(36px, 4vw, 52px);
	border-top: 1px solid var(--linea-line);
}

/*
 * A wider heading column and a slightly smaller cap than the shared
 * `--heading-column` rule, so the long sentence here lands on two lines rather
 * than three. Both numbers are needed: the size alone would not fit it, and
 * the width alone would leave it at the 52px cap and still wrap three ways.
 */
.linea-band.linea-split--narrow-first {
	grid-template-columns: 0.92fr 1.08fr;
}

.linea-band > :first-child :where(h2) {
	font-size: clamp(30px, 3.1vw, 45px);
}

.has-dark-background-color .linea-band,
.has-contrast-background-color .linea-band {
	border-color: var(--linea-line-on-dark);
}

/* Area -------------------------------------------------------------------- */

/*
 * Where the work gets done, said once.
 *
 * This was a full section head with a 66px heading, two lines of copy and
 * three link rows spread down an otherwise empty band. It is a fact, not an
 * argument: heading and copy on the left, the related pages stacked on the
 * right, one tight band.
 */
.linea-area {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
	gap: clamp(36px, 5vw, 88px);
	align-items: center;
}

.linea-area__copy :where(h2) {
	margin: 0 !important;
	max-width: 520px;
	font-size: clamp(28px, 2.6vw, 40px);
	line-height: 1.08;
	letter-spacing: -0.04em;
}

.linea-area__copy :where(p):not(.is-style-eyebrow) {
	margin: 14px 0 0 !important;
	max-width: 480px;
	color: var(--wp--preset--color--muted);
	font-size: 16px;
	line-height: 1.6;
}

/* Stacked, not three across: one hairline per row instead of six. */
.linea-area .linea-local-links {
	grid-template-columns: 1fr;
	gap: 0;
	margin-top: 0 !important;
	border-top: 1px solid var(--linea-line);
}

.linea-area .linea-local-links a {
	padding: 16px 0;
	border-top: 0;
}

@media (max-width: 860px) {
	.linea-area {
		grid-template-columns: 1fr;
		gap: 34px;
	}
}

/* Rows -------------------------------------------------------------------- */

/*
 * Two subjects, one band.
 *
 * When two sections answer the same underlying question — "what does this cost
 * me, in money and in weeks" — giving each its own band with its own 66px
 * heading spends a screen and a half saying so. A row keeps each subject's
 * heading and copy, demotes it to an H3 on a ruled line, and lets both share
 * one section head. The content below a row keeps its full width, so the price
 * and duration grids still get the measure they were designed for.
 */
.linea-rows {
	display: grid;
	gap: clamp(40px, 4.4vw, 58px);
	margin-top: clamp(36px, 4vw, 52px) !important;
}

.linea-row {
	padding-top: clamp(26px, 2.8vw, 36px);
	border-top: 1px solid var(--linea-line);
}

.linea-row__head :where(h2, h3) {
	margin: 0 !important;
	max-width: 760px;
	font-size: clamp(24px, 2.2vw, 34px);
	line-height: 1.12;
	letter-spacing: -0.03em;
	font-weight: 500;
}

.linea-row__head :where(p) {
	margin: 14px 0 0 !important;
	max-width: 640px;
	color: var(--wp--preset--color--muted);
	font-size: 17px;
	line-height: 1.6;
}

/* A row is not a section, so the section-level pin does not reach these. */
.linea-row > .linea-reading,
.linea-row > .linea-copy,
.linea-row > p {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

.has-dark-background-color .linea-row,
.has-contrast-background-color .linea-row {
	border-color: var(--linea-line-on-dark);
}

.has-dark-background-color .linea-row__head :where(p),
.has-contrast-background-color .linea-row__head :where(p) {
	color: var(--linea-muted-on-dark);
}

/* Social strip ------------------------------------------------------------ */

/*
 * A row of work photographs linking out to the feed they came from.
 *
 * It earns its place twice: it breaks up what is otherwise one continuous dark
 * run from the process band into the footer's contact band, and it is the only
 * place on the site where a visitor sees more than one photo of real work at
 * once. Built as plain `core/image` blocks so it renders with no third-party
 * request; swapping in the live feed later is one block replacement, and the
 * grid rules below apply to the plugin's own tiles too.
 */
.linea-social {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--linea-card-gap);
	margin-top: clamp(30px, 3.4vw, 44px) !important;
}

.linea-social > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

.linea-social .wp-block-image,
.linea-social figure {
	margin: 0;
	aspect-ratio: 1 / 1;
	overflow: hidden;
}

.linea-social img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.4s ease;
}

.linea-social a:hover img,
.linea-social .wp-block-image:hover img {
	transform: scale(1.04);
}

@media (max-width: 860px) {
	.linea-social {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Notes ------------------------------------------------------------------- */

/*
 * The cheap way to add a heading and a paragraph.
 *
 * A page often needs to say four more small things — a clarification, a caveat,
 * a "what about X" — and none of them deserves its own band with a 66px heading
 * and 160px of padding. Each note is a sub-heading plus a paragraph on a ruled
 * row, two to a line, so four notes cost about as much vertical space as one
 * ordinary section head. Adding a fifth is duplicating one block in the editor;
 * the grid re-flows and the rules stay aligned because grid rows share height.
 */
.linea-notes {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 0 clamp(40px, 4.5vw, 80px);
	margin-top: clamp(32px, 3.5vw, 46px) !important;
	border-top: 1px solid var(--linea-line);
}

.linea-notes__item {
	padding: 26px 0 30px;
	border-bottom: 1px solid var(--linea-line);
}

.linea-notes__item :where(h2, h3, h4) {
	margin: 0 0 10px !important;
	font-size: clamp(17px, 1.35vw, 20px);
	line-height: 1.3;
	letter-spacing: -0.02em;
	font-weight: 600;
}

.linea-notes__item :where(p) {
	margin: 0;
	max-width: 58ch;
	color: var(--wp--preset--color--muted);
	font-size: 16px;
	line-height: 1.7;
}

.linea-notes__item :where(p) + p {
	margin-top: 12px !important;
}

.linea-notes__item :where(ul, ol) {
	margin: 12px 0 0;
	padding-left: 18px;
	color: var(--wp--preset--color--muted);
	font-size: 16px;
	line-height: 1.7;
}

/* Dark and contrast bands: same rows, inverted hairlines. */
.has-dark-background-color .linea-notes,
.has-dark-background-color .linea-notes__item,
.has-contrast-background-color .linea-notes,
.has-contrast-background-color .linea-notes__item {
	border-color: var(--linea-line-on-dark);
}

.has-dark-background-color .linea-notes__item :where(h2, h3, h4),
.has-contrast-background-color .linea-notes__item :where(h2, h3, h4) {
	color: var(--wp--preset--color--on-dark);
}

.has-dark-background-color .linea-notes__item :where(p, li),
.has-contrast-background-color .linea-notes__item :where(p, li) {
	color: var(--linea-muted-on-dark);
}

@media (max-width: 860px) {
	.linea-notes {
		grid-template-columns: 1fr;
	}
}

/* Local link row -----------------------------------------------------------*/

.linea-local-links {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 16px;
	margin-top: 38px !important;
}

.linea-local-links > * {
	margin-block-start: 0 !important;
}

.linea-local-links p {
	margin: 0;
}

.linea-local-links a {
	display: flex;
	justify-content: space-between;
	gap: 16px;
	padding: 18px 0;
	border-top: 1px solid var(--linea-line);
	border-bottom: 1px solid var(--linea-line);
	font-size: 15px;
	font-weight: 600;
}

.linea-local-links a::after {
	content: "\2197";
}

/* --------------------------------------------------------------------------
   15. Contact section + Fluent Forms skin
   -------------------------------------------------------------------------- */

/*
 * The contact band is the top of the footer, not a separate light band above it.
 * One continuous dark block ends the page, with the form card as the single
 * light object in it — which is also what makes it the obvious thing to use.
 */
.linea-contact {
	background-color: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
	padding-block: clamp(80px, 9vw, 124px) clamp(56px, 6vw, 80px);
}

.linea-contact,
.linea-contact__grid {
	max-width: none;
}

.linea-contact :where(h1, h2, h3) {
	color: var(--wp--preset--color--on-dark);
}

.linea-contact .is-style-eyebrow {
	color: rgba(255, 255, 255, 0.62);
}

.linea-contact__grid {
	display: grid;
	grid-template-columns: minmax(280px, 0.8fr) minmax(0, 1.2fr);
	gap: clamp(64px, 8vw, 130px);
	align-items: start;
}

.linea-contact__grid > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

.linea-contact__copy > * {
	margin-block-start: 0;
}

.linea-contact__copy :where(h2) {
	margin: 0;
	max-width: 560px;
	font-size: clamp(38px, 4.2vw, 66px);
	line-height: 0.99;
	letter-spacing: -0.045em;
}

/*
 * The blanket `margin-block-start: 0 !important` reset in section 0 kills the
 * WordPress block gap in this column — which is what we want — but it also
 * flattened the rhythm below the heading into a single undifferentiated stack.
 * Each step is set back deliberately here, so the reset stays and the spacing
 * still reads as heading → promise → contacts → fine print.
 */
.linea-contact__text {
	max-width: 500px;
	margin: 30px 0 0 !important;
	color: var(--linea-muted-on-dark);
	font-size: 17px;
	line-height: 1.65;
}

.linea-contact__details {
	display: grid;
	gap: 14px;
	margin: 38px 0 0 !important;
	font-size: 17px;
	font-weight: 500;
}

.linea-contact__details a {
	position: relative;
	width: fit-content;
	padding-bottom: 3px;
}

.linea-contact__details a::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 1px;
	background: currentColor;
	opacity: 0.35;
	transform-origin: left;
	transition: transform 0.22s ease;
}

.linea-contact__details a {
	transition: color 0.2s ease;
}

.linea-contact__details a:hover {
	color: var(--wp--preset--color--highlight);
}

.linea-contact__details a:hover::after {
	transform: scaleX(0.35);
}

/*
 * No rule above this. A hairline here ran the full width of the copy column and
 * read as an overlong underline attached to the email address directly above
 * it; the space alone separates the fine print well enough.
 */
.linea-contact__note {
	margin: 40px 0 0 !important;
	color: rgba(255, 255, 255, 0.55);
	font-size: 14px;
	line-height: 1.55;
}

/*
 * Company facts — business ID and the work guarantee. They belong beside the
 * phone number a visitor is deciding whether to call, not in the last line of
 * the page where nobody reads them.
 */
.linea-contact__facts {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 26px;
	margin: 18px 0 0 !important;
	color: rgba(255, 255, 255, 0.62);
	font-size: 14px;
	line-height: 1.4;
}

.linea-contact__facts > span {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

/* A small marker so the facts read as a list of assurances, not a sentence. */
.linea-contact__facts > span::before {
	content: "";
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--wp--preset--color--highlight);
}

.linea-form-card {
	width: 100%;
	padding: clamp(26px, 3vw, 40px);
	background: var(--wp--preset--color--paper);
	border: 0;
}

.linea-form-card > * {
	margin-block-start: 0 !important;
}

.linea-form-card__title {
	margin: 0 0 22px;
	padding-bottom: 18px;
	border-bottom: 1px solid rgba(36, 37, 39, 0.14);
	color: var(--wp--preset--color--dark);
	font-size: clamp(24px, 2.2vw, 30px);
	line-height: 1.05;
	letter-spacing: -0.035em;
	font-weight: 500;
}

/*
 * Formation, in its bare preset: the plugin keeps behaviour and accessibility,
 * the theme supplies every visual rule below. The four short fields pair up in
 * two columns and everything else spans the card, so six fields do not stack
 * the footer twice as tall as it needs to be.
 */
.linea-form-card .formation-form__form {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 20px;
	row-gap: 4px;
	margin: 0;
}

.linea-form-card .formation-form__form > :not(.formation-field--half) {
	grid-column: 1 / -1;
}

/* The shortcode block runs wpautop over the form and leaves empty paragraphs
   between its hidden inputs; each one would add a 32px row. */
.linea-form-card .formation-form__form > p:empty,
.linea-form-card .formation-status:empty {
	display: none;
}

/* Two columns need real width; below this a paired field is ~157px. */
@media (max-width: 640px) {
	.linea-form-card .formation-form__form {
		grid-template-columns: 1fr;
	}
}

.linea-form-card .formation-field {
	margin: 0 0 16px;
	min-width: 0;
}

.linea-form-card .formation-label {
	display: block;
	margin: 0 0 9px;
	color: var(--wp--preset--color--dark);
	font-family: inherit;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.linea-form-card .formation-required {
	margin-left: 4px;
	color: #b3261e;
}

.linea-form-card .formation-input,
.linea-form-card .formation-listbox__trigger {
	display: block;
	width: 100%;
	min-height: 48px;
	margin: 0;
	padding: 12px 0 13px;
	border: 0;
	border-bottom: 1px solid rgba(36, 37, 39, 0.4);
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var(--wp--preset--color--dark);
	font-family: inherit;
	font-size: 16px;
	line-height: 1.4;
	text-align: left;
	transition: border-color 0.2s ease;
}

.linea-form-card .formation-input--textarea {
	height: 88px;
	min-height: 88px;
	resize: vertical;
}

.linea-form-card .formation-input:focus,
.linea-form-card .formation-listbox__trigger:focus {
	border-bottom-color: var(--wp--preset--color--dark);
	outline: 0;
}

.linea-form-card .formation-input:focus-visible,
.linea-form-card .formation-listbox__trigger:focus-visible {
	outline: 2px solid var(--wp--preset--color--dark);
	outline-offset: 3px;
}

.linea-form-card .formation-input::placeholder {
	color: rgba(36, 37, 39, 0.42);
}

/* The dropdown is a listbox, not a native select, so its arrow is drawn. */
.linea-form-card .formation-listbox__trigger {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	cursor: pointer;
}

.linea-form-card .formation-listbox__arrow {
	width: 9px;
	height: 9px;
	margin: -4px 4px 0 0;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: rotate(45deg);
	flex: none;
}

.linea-form-card .formation-listbox__list {
	margin: 4px 0 0;
	padding: 6px 0;
	list-style: none;
	background: var(--wp--preset--color--white);
	border: 1px solid rgba(36, 37, 39, 0.16);
	box-shadow: 0 14px 34px rgba(36, 37, 39, 0.14);
}

.linea-form-card .formation-listbox__option {
	padding: 10px 16px;
	color: var(--wp--preset--color--dark);
	font-size: 15px;
	cursor: pointer;
}

.linea-form-card .formation-listbox__option:hover,
.linea-form-card .formation-listbox__option.is-active {
	background: var(--wp--preset--color--paper);
}

.linea-form-card .formation-listbox__option[aria-selected="true"] {
	font-weight: 600;
}

.linea-form-card .formation-actions {
	margin-top: 4px;
}

.linea-form-card .formation-submit {
	appearance: none;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	min-height: 50px;
	margin: 0;
	padding: 16px 26px;
	border: 1px solid var(--wp--preset--color--dark);
	border-radius: 0;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--white);
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.linea-form-card .formation-submit:hover {
	background: transparent;
	color: var(--wp--preset--color--dark);
}

.linea-form-card .formation-submit:disabled {
	cursor: progress;
	opacity: 0.7;
}

.linea-form-card .formation-field.has-error .formation-input,
.linea-form-card .formation-field.has-error .formation-listbox__trigger {
	border-bottom-color: #b3261e;
}

.linea-form-card .formation-error,
.linea-form-card .formation-status {
	margin: 6px 0 0;
	color: #b3261e;
	font-size: 13px;
}

.linea-form-card .formation-summary {
	margin: 0 0 18px;
	padding: 12px 14px;
	border-left: 3px solid #b3261e;
	background: rgba(179, 38, 30, 0.06);
	color: #b3261e;
	font-size: 14px;
}

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */

.linea-footer {
	background-color: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
	padding-inline: max(var(--linea-gutter), calc((100% - var(--linea-wrap)) / 2));
}

.linea-footer :where(h1, h2, h3, h4, h5, h6) {
	color: var(--wp--preset--color--on-dark);
}

.linea-footer__inner {
	width: 100%;
}

.linea-footer__inner > * {
	margin-block-start: 0 !important;
}

/*
 * One grid for every footer link: three service groups and three city groups,
 * all in the same column rhythm. Merging them removed a brand column that only
 * repeated the contact band above it and a separate "by area" band that used a
 * different heading style for the same kind of list.
 */
.linea-footer__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(40px, 4vw, 64px) clamp(32px, 3.5vw, 56px);
	padding: clamp(56px, 6vw, 82px) 0 clamp(48px, 5vw, 66px);
	border-top: 1px solid var(--linea-line-on-dark);
}

.linea-footer__grid > * {
	margin-block-start: 0 !important;
	min-width: 0;
}

.linea-footer__label {
	margin: 0 0 20px !important;
	color: var(--wp--preset--color--on-dark);
	font-size: 13px;
	line-height: 1.2;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.linea-footer__links {
	display: grid;
	gap: 11px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 15px;
	line-height: 1.45;
}

.linea-footer__links a {
	display: inline-block;
	width: fit-content;
	color: rgba(255, 255, 255, 0.82);
	transition: color 0.2s ease, transform 0.2s ease;
}

.linea-footer__links a:hover {
	color: var(--wp--preset--color--highlight);
	transform: translateX(3px);
}

.linea-footer__bottom {
	display: grid;
	/*
	 * Three tracks with equal outer columns: the middle one is what actually
	 * centres against the page, not against whatever the copyright happens to
	 * be wide. Left holds the copyright, middle the secondary nav, right the
	 * agency credit.
	 */
	grid-template-columns: 1fr auto 1fr;
	gap: 30px;
	align-items: center;
	padding: 24px 0 28px;
	color: rgba(255, 255, 255, 0.48);
	font-size: 13px;
	line-height: 1.55;
}

.linea-footer__bottom > * {
	margin-block-start: 0 !important;
}

.linea-footer__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 22px;
	margin: 0;
}

.linea-footer__bottom-nav {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px 20px;
	margin: 0;
}

/* Agency credit: quiet by default, full strength on hover. */
.linea-footer__credit {
	justify-self: end;
	margin: 0 !important;
	line-height: 0;
}

.linea-footer__credit img {
	display: block;
	width: 132px;
	height: auto;
	opacity: 0.6;
	transition: opacity 0.2s ease;
}

.linea-footer__credit a:hover img,
.linea-footer__credit a:focus-visible img {
	opacity: 1;
}

.linea-footer__bottom a {
	color: rgba(255, 255, 255, 0.58);
}

.linea-footer__bottom a:hover {
	color: var(--wp--preset--color--white);
}

/* --------------------------------------------------------------------------
   17. Ordinary content pages
   -------------------------------------------------------------------------- */

.linea-page-body {
	padding-block: clamp(120px, 14vw, 190px) var(--linea-section);
	padding-inline: var(--linea-gutter);
}

.linea-page-body :where(h2) {
	margin-top: 1.6em;
}

.linea-page-body :where(h3) {
	margin-top: 1.4em;
}

/* --------------------------------------------------------------------------
   18. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1140px) {
	/*
	 * `.linea-header__cta` sits on a `wp-block-buttons` element, whose own
	 * `display: flex` from the block library has equal specificity and wins on
	 * source order — hence the extra qualifier. Without it the CTA stays on
	 * screen next to the burger and squeezes the site title onto two lines.
	 */
	.linea-header .wp-block-navigation,
	.linea-header .linea-header__cta {
		display: none;
	}

	.linea-header__toggle {
		display: inline-flex;
	}
}

@media (max-width: 1100px) {
	.linea-contact__grid {
		grid-template-columns: 1fr;
		gap: 58px;
	}

	.linea-contact__copy {
		max-width: 720px;
	}

	.linea-footer__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 1080px) {
	.linea-cards--4 {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		row-gap: 50px;
	}

	.linea-split--copy-first,
	.linea-split--even {
		grid-template-columns: 1fr 1fr;
		gap: 48px;
	}

	.linea-projects {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.linea-projects > *:nth-child(3) {
		display: none;
	}

	/*
	 * `.linea-band.linea-split--narrow-first` sets its own columns with two
	 * classes, and a media query adds no specificity — so the single-column
	 * rule below cannot reach it on its own. It has to be named here too, or
	 * the band under "Mitä työhön kuuluu" keeps its desktop two-column layout
	 * on a phone and the heading is squeezed into a third of the screen.
	 */
	.linea-split--narrow-first,
	.linea-band.linea-split--narrow-first {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	/*
	 * One column: the heading and the picture sit above the content, so there
	 * is nothing to stick beside — pinned, they would just cover the top of it.
	 */
	.linea-split--heading-column > :first-child,
	.linea-faq-split > :first-child,
	.linea-split--sticky-media > .linea-split__media {
		position: static;
		max-height: none;
	}

	.linea-split--media-narrow {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.linea-scope--two {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.linea-scope,
	.linea-duration {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 760px) {
	:root {
		--linea-gutter: 20px;
		--linea-section: 78px;
		--linea-section-tight: 62px;
	}

	.linea-section--stacked {
		padding-top: 62px;
	}

	.linea-hero__inner {
		padding-top: 130px;
		padding-bottom: 48px;
	}

	.linea-hero.wp-block-cover::after {
		background: rgba(16, 18, 15, 0.34);
	}

	.linea-hero__contacts {
		gap: 12px 20px;
		margin-top: 30px;
	}

	.linea-link-strip__inner > * {
		padding: 17px 22px;
	}

	.linea-section__head {
		grid-template-columns: 1fr;
	}

	.linea-cards--4 {
		grid-template-columns: 1fr 1fr;
		gap: 36px 12px;
	}

	.linea-card__body {
		padding-top: 13px;
	}

	.linea-card__body :where(h2, h3, h4) {
		font-size: 20px;
	}

	.linea-card__body p {
		display: none;
	}

	.linea-cards--2,
	.linea-split--copy-first,
	.linea-split--even,
	.linea-quote-panel {
		grid-template-columns: 1fr;
	}

	.linea-split--media-last .linea-split__media,
	.linea-split--media-first .linea-split__media {
		order: -1;
		aspect-ratio: 16 / 11;
	}

	.linea-facts {
		grid-template-columns: 1fr;
	}

	.linea-fact {
		padding: 20px 0;
		border-right: 0;
		border-bottom: 1px solid var(--linea-line-on-dark);
	}

	.linea-fact:last-child {
		padding-left: 0;
		border-bottom: 0;
	}

	.linea-projects {
		grid-template-columns: 1fr;
	}

	.linea-projects > *:nth-child(3) {
		display: flex;
	}

	.linea-project__media {
		aspect-ratio: 16 / 11;
	}

	.linea-quote-panel {
		padding: 32px 24px;
	}

	.linea-contact__grid {
		gap: 44px;
	}

	.linea-footer__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 34px 28px;
	}

	.linea-footer__bottom {
		grid-template-columns: 1fr;
		gap: 12px;
		padding: 22px 0 26px;
	}

	/* Stacked: everything reads from the left edge, credit last. */
	.linea-footer__bottom-nav {
		justify-content: flex-start;
	}

	.linea-footer__credit {
		justify-self: start;
		margin-top: 6px !important;
	}

	.linea-form-card {
		padding: 26px 20px;
	}

	.linea-form-card__title {
		font-size: 27px;
		margin-bottom: 22px;
		padding-bottom: 17px;
	}

	.linea-scope,
	.linea-price,
	.linea-duration,
	.linea-local-links {
		grid-template-columns: 1fr;
	}

	.linea-duration-card {
		min-height: 160px;
	}

	.linea-process {
		grid-template-columns: 1fr;
		gap: 32px;
	}

	.linea-process-card {
		min-height: 235px;
	}

	.linea-process-card::after,
	.linea-process-card:nth-child(3n)::after {
		content: "\2193";
		top: auto;
		right: auto;
		bottom: -29px;
		left: 50%;
		display: grid;
		transform: translateX(-50%);
	}

	.linea-process-card:last-child::after {
		display: none;
	}
}

@media (max-width: 480px) {
	.linea-cards--4 {
		grid-template-columns: 1fr;
		gap: 42px;
	}

	.linea-card__body p {
		display: block;
	}

	.linea-card__media {
		aspect-ratio: 4 / 3;
	}

	.linea-hero .wp-block-buttons {
		flex-direction: column;
		align-items: stretch;
	}

	.linea-hero .wp-block-button,
	.linea-hero .wp-block-button__link {
		width: 100%;
	}

	.linea-hero__contacts {
		flex-direction: column;
		align-items: flex-start;
	}

	.linea-footer__grid {
		grid-template-columns: 1fr;
		gap: 32px;
	}
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		animation-duration: 0.01ms !important;
	}
}

/* --------------------------------------------------------------------------
   19. Editor parity
   -------------------------------------------------------------------------- */

.editor-styles-wrapper .linea-header,
.editor-styles-wrapper .linea-drawer {
	position: static;
	transform: none;
	visibility: visible;
}

.editor-styles-wrapper .linea-hero.wp-block-cover {
	min-height: 620px;
}

/* --------------------------------------------------------------------------
   Landing pages (page-landing template)

   An ad lands here, so the page does one thing: get a call or a form. No
   navigation, no links away. Mobile first, because the ads are seen on a
   phone: the header is one slim row, the hero is text only, and the form
   starts inside the first screen without scrolling.
   -------------------------------------------------------------------------- */

.linea-lp-header {
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
}

.linea-lp-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	max-width: calc(1180px + 2 * clamp(18px, 4vw, 40px));
	margin: 0 auto;
	padding: 10px clamp(18px, 4vw, 40px);
	min-height: 56px;
}

.linea-lp-header__inner > *,
.linea-lp-header__brand > * {
	margin-block-start: 0 !important;
}

.linea-lp-header__brand {
	display: flex;
	align-items: center;
	gap: 10px;
}

.linea-lp-header .wp-block-site-logo img {
	width: 30px;
	height: auto;
}

.linea-lp-header .wp-block-site-title {
	color: var(--wp--preset--color--on-dark);
	font-size: 18px;
	font-weight: 500;
	letter-spacing: -0.02em;
}

.linea-lp-header__phone {
	margin: 0;
	font-size: 16px;
	font-weight: 600;
	white-space: nowrap;
}

.linea-lp-header__phone a {
	color: var(--wp--preset--color--on-dark);
	text-decoration: none;
}

.linea-lp-header__phone a::before {
	content: "";
	display: inline-block;
	width: 8px;
	height: 8px;
	margin-right: 8px;
	border-radius: 50%;
	background: var(--wp--preset--color--highlight);
	vertical-align: middle;
}

/* Hero: headline and offer beside the form, stacked on a phone. */
.linea-lp-hero {
	padding: clamp(20px, 4vw, 64px) clamp(18px, 4vw, 40px) clamp(28px, 5vw, 72px) !important;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--on-dark);
}

/* As a cover block: its own min-height and centring would push the form
   down on a phone, so the hero keeps the height of its content. The 70%
   dark overlay keeps the white headline at well over 4.5:1 on any part of
   the photo. */
.linea-lp-hero.wp-block-cover {
	min-height: 0;
	align-items: stretch;
}

.linea-lp-hero.wp-block-cover .wp-block-cover__inner-container {
	width: 100%;
	color: var(--wp--preset--color--on-dark);
}

.linea-lp-hero__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 18px;
	max-width: 1180px;
	margin: 0 auto;
}

.linea-lp-hero__grid > *,
.linea-lp-hero__copy > * {
	margin-block-start: 0 !important;
}

.linea-lp-hero .is-style-eyebrow {
	margin-bottom: 8px;
	color: var(--wp--preset--color--highlight-soft);
}

.linea-lp-hero h1 {
	margin: 0 0 12px;
	color: var(--wp--preset--color--on-dark);
	font-size: clamp(28px, 7.4vw, 54px);
	line-height: 1.04;
	letter-spacing: -0.035em;
	font-weight: 500;
	text-wrap: balance;
}

.linea-lp-offer {
	display: inline-block;
	margin: 0 0 4px;
	padding: 9px 14px;
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--dark);
	font-size: clamp(15px, 1.4vw, 18px);
	font-weight: 600;
	line-height: 1.35;
}

.linea-lp-checks {
	display: none;
	margin: 0;
	padding: 22px 0 0;
	list-style: none;
}

.linea-lp-checks li {
	position: relative;
	margin: 0 0 10px;
	padding-left: 26px;
	color: rgba(255, 255, 255, 0.86);
	font-size: 16px;
}

.linea-lp-checks li::before {
	content: "";
	position: absolute;
	left: 2px;
	top: 0.38em;
	width: 12px;
	height: 7px;
	border-left: 2px solid var(--wp--preset--color--highlight);
	border-bottom: 2px solid var(--wp--preset--color--highlight);
	transform: rotate(-45deg);
}

/* The form card on the dark hero: tighter than the footer one, so the
   button lands inside a phone's first screen. */
.linea-lp-hero .linea-form-card {
	padding: 20px 18px 18px;
	scroll-margin-top: 12px;
}

.linea-lp-hero .linea-form-card__title {
	margin-bottom: 14px;
	padding-bottom: 12px;
	font-size: 22px;
}

.linea-lp-hero .linea-form-card .formation-field {
	margin-bottom: 10px;
}

.linea-lp-hero .linea-form-card .formation-label {
	margin-bottom: 4px;
}

.linea-lp-hero .linea-form-card .formation-input {
	min-height: 42px;
	padding: 8px 0 9px;
}

.linea-lp-hero .linea-form-card .formation-input--textarea {
	height: 64px;
	min-height: 64px;
}

/* Phone and postcode are both short: keep them side by side even on a phone. */
.linea-lp-hero .linea-form-card .formation-form__form {
	grid-template-columns: 1fr 1fr;
	column-gap: 14px;
}

.linea-lp-hero .linea-form-card .formation-submit {
	justify-content: center;
	width: 100%;
	background: var(--wp--preset--color--highlight);
	border-color: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--dark);
	font-size: 16px;
}

.linea-lp-hero .linea-form-card .formation-submit:hover {
	background: var(--wp--preset--color--dark);
	border-color: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--white);
}

.linea-lp-form__note {
	margin: 10px 0 0;
	color: var(--wp--preset--color--muted);
	font-size: 13px;
	text-align: center;
}

/* Sections below the form ---------------------------------------------- */

.linea-lp-section {
	padding: clamp(44px, 7vw, 96px) clamp(18px, 4vw, 40px) !important;
}

.linea-lp-section > * {
	max-width: 1180px;
	margin-left: auto !important;
	margin-right: auto !important;
}

.linea-lp-section h2 {
	margin: 0 0 clamp(20px, 3vw, 34px);
	font-size: clamp(26px, 4vw, 42px);
	line-height: 1.08;
	letter-spacing: -0.03em;
	font-weight: 500;
	text-wrap: balance;
}

.linea-lp-gallery {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
}

.linea-lp-gallery > * {
	margin: 0 !important;
}

.linea-lp-gallery figure {
	margin: 0;
}

.linea-lp-gallery img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
}

.linea-lp-gallery figcaption {
	margin: 8px 0 0;
	color: var(--wp--preset--color--muted);
	font-size: 13px;
	line-height: 1.4;
	text-align: left;
}

.linea-lp-gallery figcaption strong {
	display: block;
	color: var(--wp--preset--color--contrast);
	font-weight: 600;
}

.linea-lp-cards {
	display: grid;
	grid-template-columns: 1fr;
	gap: 12px;
}

.linea-lp-cards > * {
	margin: 0 !important;
	padding: 22px 22px 20px;
	background: var(--wp--preset--color--white);
}

.linea-lp-cards h3 {
	margin: 0 0 6px;
	font-size: 19px;
	font-weight: 600;
	letter-spacing: -0.01em;
}

.linea-lp-cards p {
	margin: 0;
	color: var(--wp--preset--color--muted);
	font-size: 15px;
	line-height: 1.55;
}

.linea-lp-steps {
	display: grid;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: lp-step;
}

.linea-lp-steps li {
	position: relative;
	margin: 0;
	padding: 18px 0 18px 56px;
	border-top: 1px solid var(--wp--preset--color--line);
	counter-increment: lp-step;
	font-size: 16px;
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
}

.linea-lp-steps li strong {
	display: block;
	color: var(--wp--preset--color--contrast);
	font-size: 18px;
	font-weight: 600;
}

.linea-lp-steps li::before {
	content: counter(lp-step);
	position: absolute;
	left: 0;
	top: 18px;
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background: var(--wp--preset--color--dark);
	color: var(--wp--preset--color--white);
	font-weight: 600;
}

.linea-lp-faq details {
	border-top: 1px solid var(--wp--preset--color--line);
}

.linea-lp-faq details:last-child {
	border-bottom: 1px solid var(--wp--preset--color--line);
}

.linea-lp-faq summary {
	padding: 18px 32px 18px 0;
	font-size: 18px;
	font-weight: 600;
	cursor: pointer;
	position: relative;
	list-style: none;
}

.linea-lp-faq summary::-webkit-details-marker {
	display: none;
}

.linea-lp-faq summary::after {
	content: "+";
	position: absolute;
	right: 4px;
	top: 14px;
	font-size: 24px;
	font-weight: 400;
}

.linea-lp-faq details[open] summary::after {
	content: "–";
}

.linea-lp-faq details > p {
	margin: 0 0 18px;
	color: var(--wp--preset--color--muted);
	font-size: 16px;
	line-height: 1.6;
}

.linea-lp-cta {
	text-align: center;
}

.linea-lp-cta .wp-block-buttons {
	justify-content: center;
	gap: 10px;
}

.linea-lp .tbgr {
	--tbgr-font: inherit;
	--tbgr-ink: var(--wp--preset--color--contrast);
	--tbgr-muted: var(--wp--preset--color--muted);
	--tbgr-line: var(--wp--preset--color--line);
	--tbgr-card-bg: var(--wp--preset--color--white);
	--tbgr-control-bg: var(--wp--preset--color--white);
	--tbgr-control-ink: var(--wp--preset--color--contrast);
	--tbgr-radius: 0;
}

/* The theme's muted grey measures 4.29:1 on the surface tone and 4.41:1 on
   paper, just under the 4.5:1 small text needs. One step darker on this page,
   where the small text carries the promises (24 hours, the steps). */
.linea-lp-form__note,
.linea-lp-gallery figcaption,
.linea-lp-steps li,
.linea-lp-cards p,
.linea-lp-faq details > p {
	color: #555852;
}

/* An ad page asks for one thing; a "write a review" link leads off to Google. */
.linea-lp .tbgr__write {
	display: none;
}

/* Footer and the call bar ---------------------------------------------- */

.linea-lp-footer {
	padding: 22px clamp(18px, 4vw, 40px) 90px;
	background: var(--wp--preset--color--dark);
	color: rgba(255, 255, 255, 0.58);
	font-size: 13px;
}

.linea-lp-footer__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	max-width: 1180px;
	margin: 0 auto;
}

.linea-lp-footer a {
	color: rgba(255, 255, 255, 0.72);
}

/* Always within reach of a thumb on a phone; the header number does the job
   on a desktop, where a call button would be clicked by nobody. */
.linea-lp-callbar {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 900;
	margin: 0 !important;
	padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
	background: rgba(36, 37, 39, 0.96);
	box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.18);
}

.linea-lp-callbar .wp-block-buttons {
	margin: 0;
}

.linea-lp-callbar .wp-block-button__link {
	display: block;
	padding: 14px 18px;
	border-radius: 0;
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--dark);
	font-size: 17px;
	font-weight: 700;
	text-align: center;
}

/* The consent reopen button is fixed to a bottom corner; on a phone it moves
   up above the call bar instead of sitting on it. */
@media (max-width: 899px) {
	body:has(.linea-lp-callbar) #tb-consent-reopen {
		bottom: calc(84px + env(safe-area-inset-bottom));
	}
}

@media (min-width: 900px) {
	.linea-lp-hero__grid {
		grid-template-columns: 1.1fr 0.9fr;
		gap: clamp(36px, 5vw, 72px);
		align-items: center;
	}

	.linea-lp-checks {
		display: block;
	}

	.linea-lp-hero .linea-form-card {
		padding: clamp(26px, 3vw, 36px);
	}

	.linea-lp-gallery {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 16px;
	}

	.linea-lp-cards {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 16px;
	}

	.linea-lp-callbar {
		display: none;
	}

	.linea-lp-footer {
		padding-bottom: 26px;
	}
}

/* Thank-you page on the landing template: one screen, nothing else to do. */
.linea-lp-thanks {
	display: flex;
	align-items: center;
	min-height: 70svh;
}

.linea-lp-thanks .linea-lp-hero__copy {
	max-width: 760px;
	margin: 0 auto;
	text-align: center;
}

.linea-lp-thanks__lead {
	margin: 0 0 26px;
	color: rgba(255, 255, 255, 0.86);
	font-size: clamp(18px, 2vw, 22px);
	line-height: 1.5;
}

.linea-lp-thanks__actions {
	justify-content: center;
	gap: 10px;
}

.linea-lp-thanks .wp-block-button__link {
	background: var(--wp--preset--color--highlight);
	color: var(--wp--preset--color--dark);
}

.linea-lp-thanks .is-style-outline .wp-block-button__link {
	background: transparent;
	border: 1px solid rgba(255, 255, 255, 0.6);
	color: var(--wp--preset--color--white);
}

/* --------------------------------------------------------------------------
   Consent banner (TB Compliance) on a phone

   Three full buttons stacked took half a phone screen and covered the landing
   page's form. Accept and reject stay side by side with the same weight — the
   choice must be as easy either way — and settings becomes a text link below.
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
	#tb-consent-banner .tbc-banner__inner {
		padding-top: 14px;
		padding-bottom: calc(12px + env(safe-area-inset-bottom));
	}

	#tb-consent-banner .tbc-banner__title {
		margin-bottom: 4px;
		font-size: 16px;
	}

	#tb-consent-banner .tbc-banner__body {
		margin-bottom: 12px;
		font-size: 14px;
		line-height: 1.45;
	}

	#tb-consent-banner .tbc-banner__actions {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 8px;
		width: 100%;
	}

	#tb-consent-banner .tbc-button--accept,
	#tb-consent-banner .tbc-button--reject {
		width: 100%;
		margin: 0;
	}

	#tb-consent-banner .tbc-button--settings {
		grid-column: 1 / -1;
		width: auto;
		min-height: 0;
		margin: 2px auto 0;
		padding: 6px 8px;
		border: 0;
		background: transparent;
		color: inherit;
		text-decoration: underline;
		text-underline-offset: 3px;
	}
}

/* --------------------------------------------------------------------------
   reCAPTCHA notice

   The v3 badge sat over the call bar and the consent button on a phone.
   Google allows hiding it when its notice is shown in the form instead — the
   `.linea-form-legal` line under each submit button. `visibility`, not
   `display: none`: the latter can stop reCAPTCHA scoring the visit.
   -------------------------------------------------------------------------- */
.grecaptcha-badge {
	visibility: hidden;
}

.linea-form-legal {
	margin: 10px 0 0;
	color: #555852;
	font-size: 12px;
	line-height: 1.45;
}

.linea-form-legal a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.linea-lp-hero .linea-form-legal {
	margin-top: 6px;
	text-align: center;
}

/* --------------------------------------------------------------------------
   Wide content on a phone

   Tables in the blog posts and the cookie declaration are wider than a phone,
   and with the body clipped horizontally their right-hand columns simply
   disappeared. Below 782px a content table scrolls inside itself instead.
   Finnish compounds ("Kylpyhuoneremontti") are longer than a narrow card or
   table cell, so headings there hyphenate (the pages are lang="fi").
   -------------------------------------------------------------------------- */
@media (max-width: 781px) {
	.wp-block-post-content table {
		display: block;
		max-width: 100%;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	.wp-block-post-content :where(th, td) {
		min-width: 7em;
		hyphens: auto;
		overflow-wrap: break-word;
	}
}

.linea-process-card :where(h2, h3, h4),
.linea-card__body :where(h2, h3, h4),
.linea-scope-item :where(h3, h4) {
	hyphens: auto;
	overflow-wrap: break-word;
}
