/* ===========================================================
   Selzer Renovering ApS — frontpage design system

   Ported from the approved prototype (design direction "Arkitekt":
   light mode, Warm Bronze accent, Manrope headings, 4px radius,
   editorial cards). The prototype drove these through a live
   switcher; here the chosen direction is baked in as the default.
   =========================================================== */

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

:root {
  --maxw: 1200px;
  --gutter: clamp(20px, 5vw, 64px);

  /* Brand tokens — brief §11 */
  --bg: #FFFFFF;
  --surface: #F5F5F4;
  --surface-2: #ECECEA;
  --text: #111827;
  --muted: #4B5563;
  --line: #E4E4E2;
  /* Accent changed from the bronze #C08A3E on 2026-08-23 (Johan). Two reasons.
     Taste was his; the second is measurable: white text on the bronze scored
     3.02:1, under the 4.5:1 WCAG AA needs for normal text, so every button label
     on the site was hard to read. This green scores 7.84:1.
     The design reason for a *cool* accent: the photography is all brick, timber
     and sand, and a warm accent competed with it. A cool one lets the pictures
     carry the warmth and keeps the accent for signalling.
     Swapping it again is these two lines — see DECISIONS.md for the other
     candidates and their contrast figures. */
  --accent: #2E5A4B;
  --on-accent: #FFFFFF;
  /* On the dark grounds — the footer and the lightbox — the same green sinks into
     the background (2.26:1 against --text). These are its counterparts there. */
  --accent-light: #8FBFAE;
  --on-accent-light: #111827;

  --radius: 14px;
  --header-h: 80px;
  /* Hoejden paa den faste hvide bundlinje. Hero regner sin egen hoejde som
     skaermen minus denne, og body faar den som bundmargin, saa footeren kan
     scrolles helt fri af linjen. */
  --bar-h: 58px;
  --font-head: "Manrope", system-ui, sans-serif;
  --font-body: "Inter", system-ui, sans-serif;
}

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; }

/* The browser's own [hidden] rule lives in the UA stylesheet, so ANY class here
   that sets `display` silently defeats it — `.btn { display: inline-flex }` did,
   leaving all three step buttons on screen at once and forcing the form column
   wider than its grid track. Author-level and !important so it always wins. */
[hidden] { display: none !important; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--on-accent);
  padding: 12px 20px; font-weight: 600; text-decoration: none;
}
.skip-link:focus { left: 0; }

:where(a, button, input, select, textarea):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- layout helpers ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gutter); }
.section { padding-block: clamp(64px, 9vw, 132px); }

/* ---------- accent discipline, 2026-08-23 ----------
   Johan: the orange "kunne gøres lidt strammere". It was on 57 selectors — labels,
   numbers, icons, borders, tints — so it had stopped meaning anything.
   The rule from here: --accent marks what you can ACT on. Buttons, links, focus
   rings, hover, and the selected state of a control. Anything you merely look at
   is neutral. That both calms the page and makes the orange pull the eye toward
   the things we want clicked. */
.eyebrow {
  font-family: var(--font-body);
  font-size: 13px; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted);
  display: inline-flex; align-items: center; gap: 10px;
}
.eyebrow::before { content: ""; width: 26px; height: 1px; background: var(--line); display: inline-block; }

.section-head { max-width: 720px; }
.section-head h2 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(30px, 4vw, 50px);
  line-height: 1.08; letter-spacing: -0.01em;
  margin-top: 18px; text-wrap: balance;
}
.section-head p { margin-top: 18px; color: var(--muted); font-size: 19px; max-width: 60ch; text-wrap: pretty; }

/* ---------- sub-page opening ----------
   The header is solid on these pages, not floating over a photo, so the page head
   has to clear it with its own top padding rather than pulling up underneath it. */
.page-head {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(48px, 7vw, 96px);
}
.page-head h1 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(34px, 5vw, 60px);
  line-height: 1.06; letter-spacing: -0.015em;
  margin-top: 16px; max-width: 20ch; text-wrap: balance;
}
.page-lead {
  margin-top: 20px; color: var(--muted);
  font-size: clamp(17px, 2vw, 20px); max-width: 58ch; text-wrap: pretty;
}
/* The page head is tinted, so the section under it must not be, or the two run
   together the way Om and Kontakt did. */
.page-head + .section { background: var(--bg); }

/* Marks the current page in the nav. Weight rather than colour, so it still reads
   when the header is transparent over the front page's photograph. */
.nav-links a.is-current { opacity: 1; font-weight: 600; }
.nav-links a.is-current::after { transform: scaleX(1); }

/* En .page-cta hørte til her og blev fjernet igen 2026-09-01: footeren afslutter
   allerede hver side med en stor opfordring, og to i træk overbeviser mindre end
   én. Se kommentaren i inc/sections.php. */

/* ---------- billedbanner på undersider ----------
   Cirka en tredjedel af skærmen. Forsidens hero fylder det hele, og den forskel er
   med vilje: bruger man fuld skærm fem steder, er det ikke længere et virkemiddel. */
.page-head--img {
  position: relative; isolation: isolate;
  background: var(--text); border-bottom: 0;
  min-height: clamp(260px, 38vh, 420px);
  display: flex; align-items: flex-end;
  padding-block: clamp(36px, 5vw, 64px);
}
.page-head--img .wrap { position: relative; z-index: 2; width: 100%; }
.page-head-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.page-head-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Mørkest forneden, hvor teksten står, og en anelse foroven så headeren kan læses.
   Skruet op 2026-09-01: den hvide tekst var for svag mod de lysere billeder. Bemærk
   at stoppene ligger, hvor teksten faktisk er. Med bundjusteret indhold og en
   banner på 260-420 px optager overskriften og manchetten cirka 36-85 % nedefra, og
   det er dét område, der skal være mørkt, ikke midten. */
.page-head-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    rgba(12,16,24,.55) 0%,
    rgba(12,16,24,.30) 22%,
    rgba(12,16,24,.64) 55%,
    rgba(12,16,24,.90) 100%);
}
.page-head--img h1 { color: #fff; text-shadow: 0 2px 22px rgba(10,12,16,.6); }
/* Manchetten er mindre og tyndere end overskriften, så den har mest brug for det. */
.page-head--img .page-lead {
  color: rgba(255,255,255,.94);
  text-shadow: 0 1px 14px rgba(10,12,16,.55);
}
.page-head--img .eyebrow { color: rgba(255,255,255,.75); }
.page-head--img .eyebrow::before { background: rgba(255,255,255,.45); }

/* ---------- ydelser i dybden ---------- */
.svc-detail-wrap .wrap { display: flex; flex-direction: column; gap: clamp(56px, 8vw, 110px); }
.svc-detail {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 4vw, 64px); align-items: center;
}
.svc-detail--flip .svc-detail-media { order: 2; }
@media (max-width: 820px) {
  .svc-detail { grid-template-columns: 1fr; }
  .svc-detail--flip .svc-detail-media { order: 0; }
}
.svc-detail-media {
  aspect-ratio: 4/3; border-radius: var(--radius);
  overflow: hidden; background: var(--surface-2);
}
.svc-detail-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.svc-detail-body h2 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(26px, 3.2vw, 38px); line-height: 1.1; margin-bottom: 16px;
}
.svc-detail-body p { color: var(--muted); font-size: 17px; margin-bottom: 14px; text-wrap: pretty; }
.svc-detail-list { list-style: none; padding: 0; margin: 22px 0 20px; display: flex; flex-direction: column; gap: 11px; }
.svc-detail-list li { display: flex; gap: 11px; align-items: flex-start; font-size: 16px; }
.svc-detail-tick { width: 18px; height: 18px; flex: none; margin-top: 3px; color: var(--accent); }
.svc-detail-scope {
  display: flex; gap: 10px; align-items: center;
  /* Luften ovenover kom fra punktlisten, indtil den blev fjernet 2026-09-02.
     Nu bærer linjen den selv, men kun når der ikke er en liste over den. */
  margin: 22px 0 0; padding-top: 16px; border-top: 1px solid var(--line);
  font-size: 15.5px; color: var(--muted);
}
.svc-detail-list + .svc-detail-scope { margin-top: 0; }
.svc-detail-scope svg { width: 17px; height: 17px; flex: none; color: var(--muted); }

/* ---------- punkt-bånd (følger med, opgavetyper, bygningsfysik, forløb) ---------- */
.points--tint { background: var(--surface); border-block: 1px solid var(--line); }
.points-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(26px, 3.4vw, 48px); margin-top: 46px;
}
@media (max-width: 760px) { .points-grid { grid-template-columns: 1fr; } }
.point-ic {
  width: 40px; height: 40px; border-radius: 50%; margin-bottom: 14px;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text);
}
.points--tint .point-ic { background: var(--bg); }
.point-ic svg { width: 19px; height: 19px; }
.point-num {
  width: 34px; height: 34px; border-radius: 50%; margin-bottom: 14px;
  display: grid; place-items: center;
  background: var(--text); color: #fff;
  font-family: var(--font-head); font-size: 15px; font-weight: 600;
}
.point h3 { font-family: var(--font-head); font-weight: 600; font-size: 20px; margin-bottom: 8px; }
.point p { color: var(--muted); font-size: 16px; text-wrap: pretty; }

/* ---------- tjekliste ---------- */
.checklist-inner {
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(28px, 4vw, 64px); align-items: start;
}
@media (max-width: 760px) { .checklist-inner { grid-template-columns: 1fr; } }
.checklist-head h2 { font-family: var(--font-head); font-weight: 700; font-size: clamp(24px, 2.8vw, 34px); line-height: 1.12; }
.checklist-head p { margin-top: 14px; color: var(--muted); font-size: 17px; text-wrap: pretty; }
.checklist-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 13px; }
.checklist-list li {
  display: flex; gap: 12px; align-items: flex-start; font-size: 16.5px;
  padding-bottom: 13px; border-bottom: 1px solid var(--line);
}
.checklist-list li:last-child { border-bottom: 0; padding-bottom: 0; }

/* ---------- læsetekst (ydelsessiderne, 2026-09-07) ----------
   En smal, centreret tekstkolonne, fordi det her er sider, man læser, ikke
   scanner. Omkring 68 tegn er den øvre grænse for en behagelig linje; båndene og
   skemaerne omkring må gerne være bredere, teksten må ikke.
   Hed .prose til 2026-09-08. Det navn var allerede taget længere nede (68ch, ingen
   centrering, til almindelige WordPress-sider), så sektionen blev klemt ud til
   venstre. Johan: "centreres?". Kolonnen centreres af .wrap's margin: 0 auto, som
   FAQ-kolonnen; den her regel skal kun stramme bredden. */
.longform-wrap { max-width: 760px; }
.longform h2 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(26px, 3.2vw, 38px); line-height: 1.1; letter-spacing: -0.01em;
  margin: 18px 0 18px; text-wrap: balance;
}
.longform p {
  color: var(--muted); font-size: 17.5px; line-height: 1.65;
  margin-bottom: 16px; text-wrap: pretty;
}
.longform p:last-child { margin-bottom: 0; }
/* Første afsnit under overskriften i husets mørke, så indgangen har vægt. */
.longform h2 + p { color: var(--text); font-size: 19px; }
.longform-list { list-style: none; padding: 0; margin: 22px 0; display: flex; flex-direction: column; gap: 12px; }
.longform-list li { display: flex; gap: 12px; align-items: flex-start; font-size: 16.5px; line-height: 1.5; }
.longform-source {
  font-size: 14px; color: var(--muted);
  margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line);
}
.longform--tint { background: var(--surface); border-block: 1px solid var(--line); }
/* Ydelsesoversigtens "Læs mere om ..." under tidsrammen. Forælderen i selektoren
   er nødvendig: .svc-link længere nede sætter sin egen margin, og med samme
   specificitet ville den vinde på rækkefølge. */
.svc-detail-body .svc-detail-link { margin-top: 18px; }
.svc-detail-body .svc-detail-link:hover { color: var(--accent); }
.svc-detail-body .svc-detail-link:hover svg { transform: translateX(4px); }

/* ---------- FAQ ----------
   <details> frem for JavaScript: svarene står i HTML'en uanset hvad, så de bliver
   indekseret og kan læses uden script, og browseren klarer selv åbn og luk. */
.faq { background: var(--surface); border-top: 1px solid var(--line); }
.faq-wrap { max-width: 860px; }
.faq-list { margin-top: 40px; border-top: 1px solid var(--line); }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item summary {
  list-style: none; cursor: pointer; padding: 22px 0;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  font-family: var(--font-head); font-weight: 600; font-size: clamp(17px, 2vw, 20px);
  transition: color .15s;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--accent); }
.faq-item summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.faq-chev { width: 18px; height: 18px; flex: none; color: var(--muted); transform: rotate(90deg); transition: transform .22s ease, color .15s; }
.faq-item[open] .faq-chev { transform: rotate(-90deg); color: var(--accent); }
/* Under lukningen er `open` stadig sat, mens panelet glider i. Klassen vender
   pilen med det samme, så de to bevægelser sker samtidig frem for efter hinanden. */
.faq-item.is-closing .faq-chev { transform: rotate(90deg); color: var(--muted); }
/* Højden animeres på .faq-answer, så luften nedenunder skal ligge på afsnittet
   indeni. Ellers ville elementet stadig fylde sin padding ved height: 0. */
.faq-answer { overflow: hidden; }
.faq-answer p { padding-bottom: 24px; max-width: 68ch; color: var(--muted); font-size: 16.5px; text-wrap: pretty; }
@media (prefers-reduced-motion: reduce) { .faq-chev { transition: none; } }

/* image placeholder — shown until the photography is supplied */
.img-ph {
  display: grid; place-items: center;
  width: 100%; height: 100%; min-height: 160px;
  background: var(--surface-2);
  border: 1px dashed color-mix(in oklab, var(--text) 24%, var(--line));
  color: var(--muted);
}
.img-ph span { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 13px; padding: 12px; text-align: center; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-body); font-weight: 600; font-size: 16px;
  letter-spacing: .01em; padding: 15px 26px;
  border-radius: 999px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none; line-height: 1; white-space: nowrap;
  transition: transform .18s ease, background .18s ease, color .18s ease, border-color .18s ease;
}
.btn svg { width: 17px; height: 17px; }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { transform: translateY(-2px); filter: brightness(1.05); }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-lg { padding: 18px 32px; font-size: 17px; }

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 40;
  background: var(--bg);
  /* The divider is an inset shadow, not a border, so it adds no height. A 1px
     border made the box 81px while the hero was pulled up by 80, leaving a
     one-pixel strip of page background showing above the bar. */
  box-shadow: inset 0 -1px 0 transparent;
  transition: box-shadow .25s ease, background .25s ease;
}
.site-header.scrolled {
  box-shadow: inset 0 -1px 0 var(--line), 0 8px 28px -20px rgba(17, 24, 39, .5);
}

/* ---------- header over the hero photograph ----------
   Transparent while the page sits at the top, resolving to the white bar on
   scroll. JS adds .hdr-light, and only on pages that actually open with a
   full-bleed hero — elsewhere the header stays solid from the start. */
.site-header.hdr-light {
  background: transparent;
  box-shadow: none;
  /* The contrast the white nav needs comes from the hero's own scrim, not from a
     background here. A gradient on the bar is a separate element with an edge
     where it ends, and that edge is visible against the sky. */
}
.site-header.hdr-light .brand,
.site-header.hdr-light .nav-links a,
.site-header.hdr-light .nav-phone { color: #f6f3ec; }
.site-header.hdr-light .nav-links a { opacity: .92; }
.site-header.hdr-light .nav-links a:hover { color: #fff; opacity: 1; }
.site-header.hdr-light .menu-btn { color: #f6f3ec; border-color: rgba(246, 243, 236, .4); }

/* Edge to edge, not centred in the 1200px container: the logo starts at the left
   margin and the phone + CTA are pushed to the right margin. `max-width: none`
   overrides .wrap on the same element. */
.nav {
  display: flex; align-items: center;
  gap: clamp(24px, 3vw, 48px);
  height: var(--header-h);
  max-width: none;
}
/* Nav links sit next to the logo; everything else is pushed right. */
/* Telefon og CTA flyttede til bundlinjen 2026-09-02, og .nav-cta står derfor tom
   på desktop, hvor burgeren er skjult. Uden det her ville menuen klistre op ad
   ordmærket med hele højresiden tom. Nu er ordmærket i venstre kant og menuen i
   højre, hvilket holder den kant-til-kant-balance, Johan bad om. */
.nav-links { margin-left: auto; }
.nav-cta:empty { display: none; }
/* ---------- wordmark ----------
   Live text, not an image, so it inherits currentColor and flips with the header
   state on its own. Two lines, tracked so they end up about the same width:
   "Selzer" is 6 characters and "Renovering" is 10, so the smaller line needs
   markedly more letter-spacing to span the same distance. The trailing negative
   margin cancels the space letter-spacing adds after the final character. */
.brand {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .28em; text-decoration: none; color: var(--text); flex: none;
  font-family: var(--font-head); line-height: 1;
}
.brand-name {
  font-size: 21px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .30em; margin-right: -.30em;
}
.brand-sub {
  font-size: 10.5px; font-weight: 600;
  letter-spacing: .52em; margin-right: -.52em;
}
@media (max-width: 560px) {
  .brand-name { font-size: 17px; }
  .brand-sub { font-size: 9px; }
}

.nav-links { display: flex; align-items: center; gap: 32px; }
.nav-links a {
  position: relative; color: var(--text); text-decoration: none;
  font-size: 15.5px; font-weight: 500; opacity: .82;
  white-space: nowrap; padding-block: 6px;
  transition: opacity .15s, color .15s;
}
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--accent); transform: scaleX(0); transform-origin: left;
  transition: transform .22s ease;
}
.nav-links a:hover { opacity: 1; color: var(--accent); }
.nav-links a:hover::after { transform: scaleX(1); }

.nav-cta { display: flex; align-items: center; gap: 18px; }
.nav-phone {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: 15.5px; color: var(--text);
  text-decoration: none; white-space: nowrap; transition: color .15s;
}
.nav-phone svg { width: 16px; height: 16px; color: var(--muted); }
.nav-phone:hover { color: var(--accent); }

.menu-btn {
  display: none; background: none; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 9px 11px; cursor: pointer; color: var(--text);
}
.menu-btn .menu-close { display: none; }
.menu-btn[aria-expanded="true"] .menu-open { display: none; }
.menu-btn[aria-expanded="true"] .menu-close { display: block; }

/* mobile menu — the prototype's button only jumped to #kontakt; brief §19
   asks for a real mobile menu, so this is a proper disclosure panel. */
.mobile-nav {
  display: none; flex-direction: column; gap: 4px;
  padding: 8px var(--gutter) 24px;
  border-top: 1px solid var(--line); background: var(--bg);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav nav { display: flex; flex-direction: column; }
.mobile-nav a { color: var(--text); text-decoration: none; font-size: 17px; font-weight: 500; padding: 14px 0; border-bottom: 1px solid var(--line); }
.mobile-nav .mobile-nav-phone { display: inline-flex; align-items: center; gap: 9px; font-weight: 600; border-bottom: 0; }
.mobile-nav .mobile-nav-phone svg { width: 17px; height: 17px; color: var(--muted); }
.mobile-nav .btn { justify-content: center; margin-top: 8px; }

@media (max-width: 980px) {
  .nav-links, .nav-phone { display: none; }
  .menu-btn { display: inline-flex; }

  /* Headeren følger ikke med ned her. To faste linjer koster 18 % af en
     telefonskærm, og headeren indeholder mindst: kun ordmærket og burgeren.
     Bundlinjen bliver liggende, for den bærer det, der betyder noget, nemlig
     telefon og tilbudsknap. Og navigationen findes stadig to steder på hver
     side: i toppen og i footeren under Genveje.

     relative, ikke static: z-index virker kun på placerede elementer, og
     headeren skal blive ved med at ligge over hero-fotoet, som trækkes op
     under den. */
  .site-header { position: relative; }
  .mobile-nav:not([hidden]) { display: flex; }
}
@media (max-width: 768px) {
  /* Set on the token, not on .nav — the hero's pull-up has to match the bar. */
  :root { --header-h: 64px; }
  .nav { gap: 12px; }
  .nav-cta { gap: 9px; }
  .nav-cta .btn-primary { padding: 9px 15px; font-size: 14px; }
  .nav-cta .btn-primary svg { display: none; }
  .menu-btn { padding: 9px 10px; }
}

/* ---------- hero ---------- */
.hero { position: relative; }
.hero h1 {
  font-family: var(--font-head); font-weight: 700;
  letter-spacing: -0.015em; line-height: 1.06;
}

/* The three primary services are the whole hero now. Each word stays intact and
   carries its own separator, so wrapping breaks between words only. */
.hero-title { display: flex; flex-wrap: wrap; column-gap: 0; row-gap: .1em; }
/* Over stablingsgrænsen må den aldrig brække. Skriftstørrelsen er sat, så den
   passer, og målingen i site.js regner på den samlede bredde i én linje. */
@media (min-width: 961px) { .hero--full .hero-title { flex-wrap: nowrap; } }
.hero-word { white-space: nowrap; }
.hero-sep { display: inline-block; padding-inline: .38em; opacity: .55; font-weight: 400; }

/* Below this the three words no longer fit on one line, and letting them wrap
   would strand a separator at the end of a line. Stack them instead — three words,
   one per line, separators dropped. */
/* Grænsen er hævet fra 620 til 960 px, fordi skriften nu er sat til at fylde
   bredden. Mellem de to tal ville strengen være få pixels for bred og brække på
   et tilfældigt sted. Så hellere stable de tre ord bevidst. */
@media (max-width: 960px) {
  .hero-title { flex-direction: column; row-gap: 0; }
  .hero-sep { display: none; }
  /* Skriftstørrelsen for stablet tilstand står IKKE her. Den almindelige
     .hero--full h1 længere nede i filen har samme specificitet, og den sidste
     regel vinder uanset mediegrænse. Så den er flyttet ned bagefter. */
}

/* The header is sticky and so occupies its own height in the flow. Pulling the
   hero up by exactly that height puts the photograph behind the bar, which is
   what makes the transparent state read as part of the image. The header keeps
   z-index 40, so it still paints on top. */
.hero--full { margin-top: calc(-1 * var(--header-h)); }
.hero--full .hero-stage {
  position: relative;
  /* Fuld skærmhøjde, 2026-08-23. Startede som et loft på 820px, som fik billedet
     til at stoppe for tidligt på store skærme (Johan). Derefter kort på 92vh, så
     en stribe af næste afsnit var synlig og fortalte, at der var mere at scrolle
     til. Nu fuld højde efter ønske om fullscreen-effekt ved ankomst.
     Tilbage til mellemvarianten: clamp(520px, 92vh, 1200px) og 92svh nedenunder.

     svh er den vigtige af de to enheder på mobil. 100vh regner browserens egen
     adressebjælke med, selvom den glider væk, når man scroller, så bunden af
     billedet ville blive skåret af. svh måler den synlige højde med bjælken på.
     Browsere uden svh falder tilbage på linjen ovenover.

     max() frem for bare 100svh, så et meget lavt vindue ikke maser overskriften. */
  /* Skærmen minus brættet, så foto og bræm tilsammen fylder præcis ét skærmbillede
     og brættet er synligt uden at scrolle. Det er hele idéen i konstruktionen fra
     pihlmann.dk, som Johan sendte: teksten hviler på billedets nederste kant, og
     den hvide stribe under bærer resten. */
  min-height: max(520px, calc(100vh  - var(--bar-h)));
  min-height: max(520px, calc(100svh - var(--bar-h)));
  display: flex; align-items: flex-end;
}
.hero--full .hero-media-bg { position: absolute; inset: 0; background: linear-gradient(150deg, #3a342c 0%, #2a2620 55%, #211d18 100%); }
.hero--full .hero-scrim {
  position: absolute; inset: 0; pointer-events: none;
  /* The first stop carries the header: the bar itself is transparent, so the nav
     gets its contrast from here. Faded out gradually by 22% — well past the bar —
     so it reads as light falling off in the photograph, with no edge anywhere. */
  background: linear-gradient(180deg,
    rgba(15,20,30,.40) 0%,
    rgba(15,20,30,.06) 22%,
    rgba(15,20,30,.06) 42%,
    rgba(15,20,30,.50) 100%);
}
/* Kant til kant, ikke i 1200 px-kassen. Johan 2026-09-03: overskriften skal være
   "som Pihlmanns", og deres spænder hele skærmens bredde. Hero'en får sin egen,
   smallere yderkant end resten af siden, netop for at give plads til den. */
.hero--full .hero-stage > .wrap {
  max-width: none;
  padding-inline: clamp(16px, 2vw, 28px);
}
.hero--full .hero-copy {
  position: relative; color: #f6f3ec;
  /* Skriftens bundlinje ligger lige over billedets kant. Kun krogene på g'erne i
     Ombygning og Tilbygning bryder den, og det er med vilje: selve teksten skal
     ikke rage ned over kanten, kun de nedstreger der hænger under bogstaverne.

     Nul luft under er præcis dét. Fordi linjehøjden er 0,98, ligger linjeboksens
     bund et lille stykke over bogstavernes egne nedstreger, så baselinen holder
     sig over kanten mens krogene passerer den.

     z-index skal blive: bundlinjen ligger fast med z-index 45 og ville ellers
     male hen over krogene, så de så afskårne ud frem for gennemgående. */
  padding-bottom: 0;
  z-index: 46;
  display: flex; flex-direction: column;
}
/* Sized to hold all three words on one line down to roughly tablet width; below
   that it wraps word by word rather than shrinking to an unreadable size. */
/* Sat til at fylde bredden. "Renovering · Ombygning · Tilbygning" er cirka 35 tegn,
   som i denne skrift fylder omtrent 17,5 gange skriftstørrelsen. Ved 5,5vw og en
   yderkant på 2vw lander strengen derfor stort set på skærmens fulde bredde,
   uanset hvor bred skærmen er. Loftet på 132 px er til meget brede skærme. */
/* Tungere og tættere, efter Pihlmann. Vægt 800 frem for 700, og bogstaverne
   rykket tættere sammen: en stor overskrift bliver ikke solid af vægt alene, det
   er lige så meget den luft, der forsvinder mellem bogstaverne.

   Størrelsen her er et SIKKERT gulv, ikke det endelige tal. site.js måler den
   faktiske bredde af strengen og skruer op, til den lige akkurat fylder linjen.
   Grunden er, at den rigtige størrelse ikke kan regnes ud på forhånd: den
   afhænger af skriftens egne bogstavbredder, og et gæt her brækkede teksten om
   på to linjer. Uden JavaScript står den bare på det sikre tal, en anelse for
   lille, men på én linje. */
.hero--full h1 {
  font-weight: 800;
  font-size: clamp(30px, 4.6vw, 136px);
  line-height: .98; letter-spacing: -0.038em;
  color: #fff; text-shadow: 0 2px 24px rgba(10,12,16,.45);
}
/* Stablet tilstand. Står HER og ikke oppe i mediegrænsen ved linje 457, hvor den
   hørte hjemme logisk: de to regler har samme specificitet, så den sidste i filen
   vinder uanset mediegrænse. Stod den deroppe, kørte telefonen på desktop-tallet.
   Hvert ord fylder sin egen linje, og det længste er "Renovering" på 10 tegn,
   altså cirka 5 gange skriftstørrelsen. */
@media (max-width: 960px) {
  .hero--full h1 { font-size: clamp(34px, 14vw, 96px); }
}
.hero-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- den faste hvide bundlinje ----------
   Efter pihlmann.dk, som Johan sendte. En tynd hvid stribe fastgjort nederst i
   skærmbilledet, som bliver liggende hele vejen ned gennem siden.

   Den gør to ting på én gang. Den lader forsidefotoet stå ubehandlet, fordi
   overskriften hviler på billedets nederste kant med striben lige under i stedet
   for på et slør hen over motivet. Og den holder telefon og tilbudsknap synlige
   overalt, hvor de før kun var i toppen. */
.site-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  min-height: var(--bar-h);
  /* Kun plads til knappen og lidt luft. Knappen er 39 px høj, så 58 px giver
     knap 10 px over og under.
     Den tidligere luft på 25 px i toppen er væk igen. Den var der for heroens
     nedstreger, men de hænger kun 11 px ned og sidder yderst til højre, uden for
     knappens felt, fordi overskriften bruger en smallere yderkant end linjen. */
  display: flex; align-items: center;
  background: var(--bg); border-top: 1px solid var(--line);
  box-shadow: 0 -8px 28px -22px rgba(17, 24, 39, .5);
}
.site-bar-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; width: 100%;
  /* Kant til kant, ikke en indholdskasse i midten. Samme greb som .nav i headeren,
     og med vilje samme --gutter: så flugter linjens venstre tekst lodret med
     ordmærket, og knappen til højre med menuens yderkant. */
  max-width: none;
}
.site-bar-label { font-size: 14px; color: var(--muted); }
.site-bar-actions { display: flex; align-items: center; gap: 18px; flex: none; }
.site-bar-phone {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 15px; font-weight: 500; color: var(--text);
  text-decoration: none; white-space: nowrap; transition: color .15s;
}
.site-bar-phone svg { width: 16px; height: 16px; color: var(--muted); }
.site-bar-phone:hover { color: var(--accent); }
.site-bar-cta { padding: 11px 20px; font-size: 15px; }

/* Siden skal kunne scrolles helt til ende uden at linjen dækker footeren. */
body { padding-bottom: var(--bar-h); }

@media (max-width: 760px) {
  :root { --bar-h: 54px; }
  /* Teksten er det, der må vige på en telefon. Kontaktvejene er hele pointen. */
  .site-bar-label { display: none; }
  .site-bar-inner { justify-content: center; }
  .site-bar-actions { gap: 12px; }
}
@media (max-width: 420px) {
  .site-bar-phone span, .site-bar-phone { font-size: 14px; }
  .site-bar-cta { padding: 10px 16px; font-size: 14px; }
}

/* ---------- hero i sort skrift ----------
   Alt herunder er ét sammenhængende alternativ til den hvide hero, slået til med
   'ink' => 'dark' i inc/content.php. Rul tilbage ved at skrive 'light' i stedet;
   intet herunder skal slettes, det bliver bare liggende ubrugt.

   Bemærk hvorfor sløret vendes og ikke bare fjernes: sort skrift oven på et
   fotografi kræver MERE hjælp end hvid, fordi et billede indeholder mange mørke
   detaljer, som sort tekst forsvinder ned i. Den lyse vask er kraftigere end den
   mørke af samme grund. Prisen er, at billedet bliver lysere og lidt mælket, og
   det er præcis dét, der skal vurderes med det rigtige foto på plads. */
/* Sløret hen over HELE fotoet er væk 2026-09-02. Det var Johans "hvidmelerede
   kant hele vejen rundt", og han havde ret: det gjorde billedet mælket.
   Tilbage er en svag lysning i toppen alene, og kun så langt ned som headeren
   rækker. Den sorte menu skal kunne læses, uanset hvad der ligger bag den, men
   nederste to tredjedele af billedet er nu helt urørt. */
.hero-ink-dark .hero--full .hero-scrim {
  background: linear-gradient(180deg,
    rgba(255,255,255,.62) 0%,
    rgba(255,255,255,.30) 9%,
    rgba(255,255,255,0)   20%);
}
.hero-ink-dark .hero--full .hero-copy { color: var(--text); }
/* Ingen skygge. Den var en nødløsning fra dengang teksten lå på et uroligt motiv;
   på det nuværende billede måler sort skrift 7,14:1, hvilket er rigeligt uden
   hjælp. En skygge ville kun gøre kanterne uskarpe. Skiftes billedet til et
   mørkere eller mere uroligt, skal kontrasten måles igen. */
.hero-ink-dark .hero--full h1 { color: var(--text); }

/* Headeren svæver hen over billedet, så ordmærket og menuen skal med over. */
.hero-ink-dark .site-header.hdr-light .brand,
.hero-ink-dark .site-header.hdr-light .nav-links a,
.hero-ink-dark .site-header.hdr-light .nav-phone { color: var(--text); }
.hero-ink-dark .site-header.hdr-light .nav-links a { opacity: .84; }
.hero-ink-dark .site-header.hdr-light .nav-links a:hover { color: var(--accent); opacity: 1; }
.hero-ink-dark .site-header.hdr-light .nav-phone svg { color: var(--muted); }
.hero-ink-dark .site-header.hdr-light .menu-btn {
  color: var(--text); border-color: rgba(17, 24, 39, .28);
}
.hero--full .hero-img { position: absolute; inset: 0; }
.hero--full .img-ph { position: absolute; inset: 0; border: 0; }

@media (max-width: 768px) {
  /* Skal trække bundlinjen fra, ligesom desktop-reglen. Gjorde den ikke, og det
     var fejlen: billedet fyldte hele skærmen, den faste bundlinje lagde sig oven
     på de nederste 54 px, og dér står overskriften. Den forsvandt bag linjen. */
  .hero--full .hero-stage {
    min-height: max(420px, calc(100vh  - var(--bar-h)));
    min-height: max(420px, calc(100svh - var(--bar-h)));
  }
}

/* ---------- om johan ---------- */
.om { background: var(--surface); border-block: 1px solid var(--line); }
/* Om ligger direkte oven på kontaktsektionen, så deres to 1px-kanter mødes og
   tegner én 2px-streg: kanter på blokelementer lægges ikke sammen som i en tabel.
   Om beholder sin egen underkant, og kontakt dropper sin overkant. */
.om + .contact { border-top: 0; }
.om-grid { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: clamp(32px, 5vw, 72px); align-items: center; }
@media (max-width: 860px) { .om-grid { grid-template-columns: 1fr; } }
.om-media { aspect-ratio: 4/5; border-radius: var(--radius); overflow: hidden; }
.om-portrait { width: 100%; height: 100%; object-fit: cover; display: block; }
.portrait-ph {
  width: 100%; height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 14px;
  background: var(--surface-2);
  border: 1px dashed color-mix(in oklab, var(--text) 24%, var(--line));
  color: var(--muted); text-align: center; padding: 20px;
}
.portrait-ph svg { color: var(--muted); opacity: .7; }
.portrait-ph span { font-size: 14px; font-family: ui-monospace, "SF Mono", Menlo, monospace; }
.om-copy h2 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(28px, 3.6vw, 46px); line-height: 1.08;
  margin-top: 16px; letter-spacing: -0.01em;
}
.om-para { margin-top: 18px; color: var(--muted); font-size: 18px; text-wrap: pretty; }
.om-points { list-style: none; margin: 26px 0 28px; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.om-points li { display: flex; align-items: center; gap: 13px; font-size: 16.5px; font-weight: 500; }
.om-ic {
  width: 36px; height: 36px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text);
}
.om-ic svg { width: 18px; height: 18px; }

/* ---------- services ----------
   The prototype's saved defaults rendered the flat [data-vibe="editorial"]
   variant, but the hand-off spec is explicit: ship the default card style and
   drop the variant. Bordered surface card, lifting into a shadow on hover. */
.services-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(18px, 2.4vw, 30px); margin-top: 54px; }
@media (max-width: 820px) { .services-grid { grid-template-columns: 1fr; } }
.svc {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.svc:hover {
  transform: translateY(-4px);
  /* Neutral on hover: the orange belongs to the "Læs mere" link inside the card,
     not to the whole card, so the eye is sent to the thing that is clickable. */
  border-color: color-mix(in oklab, var(--text) 26%, var(--line));
  box-shadow: 0 22px 48px -28px rgba(40, 34, 24, .45);
}
.svc-media { aspect-ratio: 16/11; width: 100%; background: var(--surface-2); overflow: hidden; }
.svc-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease; }
.svc:hover .svc-media img { transform: scale(1.04); }
.svc-body { padding: 26px 26px 30px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
.svc-num { font-family: var(--font-head); font-size: 14px; color: var(--muted); letter-spacing: .04em; }
.svc h3 { font-family: var(--font-head); font-weight: 600; font-size: 26px; line-height: 1.1; }
.svc p { color: var(--muted); font-size: 16px; flex: 1; text-wrap: pretty; }
.svc-link {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 600; font-size: 15px; color: var(--text);
  text-decoration: none; margin-top: 4px;
}
.svc-link svg { width: 16px; height: 16px; transition: transform .18s ease; }
.svc:hover .svc-link { color: var(--accent); }
.svc:hover .svc-link svg { transform: translateX(4px); }

/* ---------- process ---------- */
.process { background: var(--surface); border-block: 1px solid var(--line); }
.process-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 48px) clamp(20px, 3vw, 44px); margin-top: 56px;
}
@media (max-width: 900px) { .process-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px) { .process-grid { grid-template-columns: 1fr; } }
.step { position: relative; padding-top: 30px; border-top: 2px solid var(--line); }
.step-num {
  position: absolute; top: -16px; left: 0;
  font-family: var(--font-head); font-size: 15px; font-weight: 600;
  color: #fff; background: var(--text);
  width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%;
}
.step h3 { font-family: var(--font-head); font-weight: 600; font-size: 22px; margin-bottom: 10px; }
.step p { color: var(--muted); font-size: 16px; text-wrap: pretty; }
.process .section-head h2 em { font-style: italic; }

/* ---------- projekter ---------- */
.projekt-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(20px, 2.6vw, 34px); margin-top: 54px; }
@media (max-width: 820px) { .projekt-grid { grid-template-columns: 1fr; } }
.projekt {
  position: relative; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; display: flex; flex-direction: column;
  transition: transform .2s ease, box-shadow .2s ease;
}
.projekt:hover { transform: translateY(-4px); box-shadow: 0 22px 48px -28px rgba(40,34,24,.4); }
.projekt-btn { all: unset; display: flex; flex-direction: column; cursor: pointer; width: 100%; box-sizing: border-box; }
.projekt-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.projekt-media { position: relative; display: block; aspect-ratio: 4/3; background: var(--surface-2); overflow: hidden; }
.projekt-media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease, opacity .45s ease; }
.projekt:hover .projekt-media img { transform: scale(1.04); }
.projekt-before { position: absolute; inset: 0; }
.projekt-after { position: absolute; inset: 0; z-index: 1; }
.projekt.has-ba:hover .projekt-after { opacity: 0; }
.projekt-ba {
  position: absolute; z-index: 2; top: 12px; left: 12px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  /* Same dark pill as .projekt-count in the opposite corner — two badges on one
     photograph should not be two different colours. */
  color: #fff; background: rgba(17,24,39,.72); backdrop-filter: blur(6px);
  padding: 6px 12px; border-radius: 999px;
}
.projekt.has-ba:hover .projekt-ba::after { content: " · før"; }
.projekt-count {
  position: absolute; z-index: 2; bottom: 12px; right: 12px;
  font-size: 12px; font-weight: 600; letter-spacing: .03em; color: #fff;
  background: rgba(17,24,39,.72); backdrop-filter: blur(6px);
  padding: 6px 12px; border-radius: 999px;
}
.projekt-body { display: flex; flex-direction: column; gap: 8px; padding: 22px 24px 26px; }
.projekt-type { font-size: 13px; font-weight: 600; letter-spacing: .04em; color: var(--muted); text-transform: uppercase; }
.projekt-body h3 { font-family: var(--font-head); font-weight: 600; font-size: 23px; line-height: 1.12; }
.projekt-body p { color: var(--muted); font-size: 15.5px; text-wrap: pretty; }
.projekt-note { margin-top: 30px; color: var(--muted); font-size: 15px; text-align: center; }

/* lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: 90; background: rgba(10,12,16,.94);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 24px;
}
.lightbox[hidden] { display: none; }
.lb-inner { display: flex; align-items: center; gap: 14px; max-width: min(1100px, 94vw); }
.lb-img { max-width: min(960px, 82vw); max-height: 76vh; width: auto; height: auto; object-fit: contain; border-radius: 4px; display: block; }
.lb-nav, .lb-close {
  all: unset; cursor: pointer; display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: rgba(255,255,255,.12); color: #fff; flex: none; transition: background .15s;
}
.lb-nav:hover, .lb-close:hover { background: var(--accent-light); color: var(--on-accent-light); }
.lb-nav svg, .lb-close svg { width: 22px; height: 22px; }
.lb-close { position: absolute; top: 22px; right: 22px; }
.lb-tabs { display: flex; gap: 4px; padding: 4px; background: rgba(255,255,255,.1); border-radius: 999px; }
.lb-tabs[hidden] { display: none; }
.lb-tabs button {
  all: unset; cursor: pointer; font-family: var(--font-body);
  font-size: 14px; font-weight: 600; color: rgba(255,255,255,.72);
  padding: 9px 24px; border-radius: 999px; transition: background .15s, color .15s;
}
.lb-tabs button:hover { color: #fff; }
.lb-tabs button.active { background: var(--accent-light); color: var(--on-accent-light); }
.lb-cap { display: flex; flex-direction: column; align-items: center; gap: 3px; color: #fff; text-align: center; }
.lb-cap b { font-family: var(--font-head); font-size: 17px; font-weight: 700; }
.lb-cap span { font-size: 14px; opacity: .7; }
@media (max-width: 620px) { .lb-nav { width: 40px; height: 40px; } .lb-img { max-width: 72vw; } }

/* ---------- contact ---------- */
/* Hvid, ikke grå. Om ligger nu lige ovenover og er også grå, så de to smeltede
   sammen til ét langt felt. Ved at gøre kontakt hvid falder hele siden i et rent
   skiftevis mønster igen: ydelser hvid, proces grå, projekter hvid, om grå,
   kontakt hvid, footer mørk. Hver overgang er nu et faktisk farveskift.
   Formularkortet er selv hvidt og mistede sin kant mod en hvid bund, så det har
   fået en blød skygge i stedet. Se form.lead nedenfor. */
.contact { background: var(--bg); border-top: 1px solid var(--line); }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(36px, 5vw, 80px); }
@media (max-width: 820px) { .contact-grid { grid-template-columns: 1fr; } }
.contact-aside { display: flex; flex-direction: column; gap: 26px; }
.contact-title {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(28px, 3.8vw, 48px); line-height: 1.06;
  margin-top: 16px; letter-spacing: -0.01em;
}
.contact-sub { margin-top: 16px; color: var(--muted); font-size: 18px; max-width: 44ch; }
.contact-points { display: flex; flex-direction: column; gap: 18px; margin-top: 6px; }
.cp { display: flex; gap: 14px; align-items: flex-start; }
.cp-text { display: flex; flex-direction: column; gap: 2px; }
.cp-text b { font-family: var(--font-head); font-weight: 700; font-size: 17px; }
.cp-text span { color: var(--muted); font-size: 15.5px; }
.cp-ic {
  width: 44px; height: 44px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-2); color: var(--text);
}
.cp-ic svg { width: 20px; height: 20px; }

form.lead {
  --lead-pad: clamp(22px, 3vw, 34px);
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  /* Kortet er hvidt og står nu på hvid bund, så kanten alene var for spinkel til
     at holde det sammen. Skyggen løfter det fra fladen i stedet. */
  box-shadow: 0 24px 60px -34px rgba(17, 24, 39, .35), 0 2px 6px -2px rgba(17, 24, 39, .06);
  padding: var(--lead-pad); display: flex; flex-direction: column; gap: 16px;
  overflow: hidden; /* lets the steps bar and foot bleed to the card edges */
}
.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 13.5px; font-weight: 600; letter-spacing: .02em; }
.field .req { color: var(--accent); }
.field input, .field textarea, .field select {
  font-family: var(--font-body); font-size: 16px; color: var(--text);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: calc(var(--radius) * .8); padding: 13px 15px; width: 100%;
  transition: border-color .15s, box-shadow .15s;
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 22%, transparent);
}
.field textarea { resize: vertical; min-height: 104px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 520px) { .field-row { grid-template-columns: 1fr; } }
.field-error { font-size: 13px; color: #b3261e; font-weight: 500; }
.form-error {
  font-size: 15px; color: #b3261e; font-weight: 500;
  background: #fdecea; border: 1px solid #f5c2bd;
  border-radius: calc(var(--radius) * .8); padding: 12px 14px;
}
.form-meta { font-size: 13px; color: var(--muted); }
.form-ok {
  background: color-mix(in oklab, var(--accent) 12%, var(--bg));
  border: 1px solid color-mix(in oklab, var(--accent) 40%, var(--line));
  border-radius: var(--radius); padding: 44px 30px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.form-ok-ic {
  width: 56px; height: 56px; display: grid; place-items: center; border-radius: 50%;
  background: var(--accent); color: var(--on-accent); margin-bottom: 12px;
  animation: okpop .45s cubic-bezier(.34, 1.56, .64, 1) both;
}
.form-ok-ic svg { width: 28px; height: 28px; stroke-width: 2.4; }
@keyframes okpop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.form-ok h3 { font-family: var(--font-head); font-weight: 600; font-size: 26px; margin-bottom: 8px; }
.form-ok p { color: var(--muted); }

/* honeypot — visually gone, still reachable to the bots that fill it */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- lead form: steps ----------
   The step chrome only appears once site.js takes over. Without JS the steps
   bar, Videre/Tilbage and the recap stay [hidden], every pane is open and the
   form submits as one page. */
.steps-bar {
  list-style: none; display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px;
  margin: calc(-1 * var(--lead-pad)) calc(-1 * var(--lead-pad)) 8px;
  padding: 18px var(--lead-pad);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  pointer-events: none; user-select: none; cursor: default;
}
.steps-bar[hidden] { display: none; }
.stepdot { display: flex; align-items: center; gap: 7px; padding-top: 10px; border-top: 2px solid var(--line); transition: border-color .3s ease; }
.stepdot.now, .stepdot.done { border-top-color: var(--accent); }
.stepdot-num {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; font-family: var(--font-head);
  color: var(--muted); opacity: .65; transition: color .25s, opacity .25s;
}
.stepdot-num svg { width: 12px; height: 12px; stroke-width: 2.8; }
.stepdot-num::after { content: "."; }
.stepdot.done .stepdot-num::after, .stepdot.now .stepdot-num::after { content: ""; }
.stepdot.now .stepdot-num { color: var(--accent); opacity: 1; }
.stepdot.done .stepdot-num { color: var(--accent); opacity: .8; }
.stepdot-label { font-size: 12.5px; font-weight: 500; letter-spacing: .01em; color: var(--muted); line-height: 1.25; }
.stepdot.now .stepdot-label { color: var(--text); font-weight: 600; }
@media (max-width: 520px) { .stepdot:not(.now) .stepdot-label { display: none; } }

.step-pane { display: flex; flex-direction: column; gap: 16px; }
.step-pane[hidden] { display: none; }
.lead[data-stepped] .step-pane { animation: stepin .32s ease both; }
@keyframes stepin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Wrapping row: when "Tilbage" + the long final label no longer fit side by side,
   the primary drops onto its own full-width line instead of breaking its text.
   That also keeps the row's min-content at one button rather than the sum, so it
   can't force the grid column wider than its half. */
.step-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
/* flex-basis auto, so the button asks for its natural single-line width first and
   only grows to fill. It keeps `.btn`'s white-space: nowrap — the label must never
   break across two lines and leave the button taller than "Tilbage" beside it. */
.step-actions .btn-primary { flex: 1 1 auto; justify-content: center; }

/* Keeps "Tilbage" and the submit button on one row further down the range. With the
   short CTA there is room at full size until roughly here; below it, trimming the
   button beats dropping it onto its own line. */
@media (max-width: 900px) {
  .step-actions .btn-lg { padding-inline: 20px; font-size: 16px; }
}
.step-actions .btn-ghost { flex: none; }
.step-actions .btn:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.step-actions .btn-ghost svg { width: 15px; height: 15px; }
.lead-foot {
  margin: 4px calc(-1 * var(--lead-pad)) calc(-1 * var(--lead-pad));
  padding: 20px var(--lead-pad);
  background: var(--surface-2);
  border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 12px;
}
.lead-foot .form-meta { margin: 0; text-align: center; }

.lead-recap {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 14.5px; font-weight: 500;
}
.lead-recap[hidden] { display: none; }
.lead-recap-ic { width: 22px; height: 22px; flex: none; display: grid; place-items: center; border-radius: 50%; background: var(--text); color: #fff; }
.lead-recap-ic svg { width: 13px; height: 13px; stroke-width: 2.8; }
.lead-recap-edit {
  all: unset; cursor: pointer; margin-left: auto;
  font-size: 13.5px; font-weight: 600; color: var(--accent);
  text-decoration: underline; text-underline-offset: 3px;
}
.lead-recap-edit:hover { opacity: .75; }

/* ---------- lead form: choices ---------- */
.pickset { border: 0; padding: 0; margin: 0; min-width: 0; }
/* Second question on step 1, revealed once a project type is chosen. */
.is-revealing { animation: revealin .34s cubic-bezier(.3, .7, .4, 1) both; }
@keyframes revealin {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.pickset legend { padding: 0; font-size: 13.5px; font-weight: 600; letter-spacing: .02em; margin-bottom: 7px; }
.choice-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
@media (max-width: 620px) { .choice-grid { grid-template-columns: repeat(2, 1fr); } }
.choice input, .chip-pick input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.choice {
  position: relative; box-sizing: border-box; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  padding: 16px 8px 14px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); text-align: center;
  transition: border-color .18s, background .18s, transform .18s;
}
.choice:hover { border-color: color-mix(in oklab, var(--accent) 55%, var(--line)); transform: translateY(-2px); }
.choice:focus-within, .chip-pick:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.choice-ic {
  width: 42px; height: 42px; display: grid; place-items: center; border-radius: 50%;
  /* Neutral until picked — .choice.on below turns it orange. The colour marks the
     choice you made, not every choice on offer. */
  background: var(--surface-2); color: var(--muted);
  transition: background .18s, color .18s;
}
.choice-ic svg { width: 19px; height: 19px; }
.choice-label { font-size: 13.5px; font-weight: 600; line-height: 1.2; color: var(--text); }
.choice.on { border-color: var(--accent); background: color-mix(in oklab, var(--accent) 9%, var(--surface)); }
.choice.on .choice-ic { background: var(--accent); color: var(--on-accent); }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-pick {
  position: relative; box-sizing: border-box; cursor: pointer;
  font-size: 14px; font-weight: 500; color: var(--muted);
  padding: 9px 16px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); transition: border-color .18s, background .18s, color .18s;
}
.chip-pick:hover { border-color: color-mix(in oklab, var(--accent) 55%, var(--line)); color: var(--text); }
.chip-pick.on { border-color: var(--accent); background: var(--accent); color: var(--on-accent); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .choice, .chip-pick, .choice-ic, .stepdot { transition: none; }
  .choice:hover { transform: none; }
  .lead[data-stepped] .step-pane, .form-ok-ic, .is-revealing { animation: none; }
}

/* ---------- footer ---------- */
.site-footer { background: var(--text); color: rgba(255,255,255,.86); }
.footer-cta {
  position: relative; overflow: hidden;
  padding-block: clamp(64px, 9vw, 118px); text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 22px;
  border-bottom: 1px solid rgba(255,255,255,.12);
}
.footer-cta > * { position: relative; z-index: 1; }
/* The one primary button that sits on the dark ground. The light accent with dark
   text reads at 8.64:1 here; the dark accent would be 2.26:1 and all but vanish. */
.footer-cta .btn-primary { background: var(--accent-light); color: var(--on-accent-light); }
.footer-cta-mark {
  position: absolute; z-index: 0; right: -30px; bottom: -70px;
  width: clamp(260px, 26vw, 400px); height: auto;
  color: #fff; opacity: .05; pointer-events: none;
}
@media (max-width: 820px) { .footer-cta-mark { display: none; } }
.footer-cta h2 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(30px, 4.4vw, 56px); line-height: 1.05;
  color: var(--bg); max-width: 18ch; text-wrap: balance;
}
.footer-cta p { color: rgba(255,255,255,.70); max-width: 52ch; }
.footer-cta-alt {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 15px; font-weight: 500; color: rgba(255,255,255,.66);
  text-decoration: none; transition: color .15s;
}
.footer-cta-alt svg { width: 16px; height: 16px; color: rgba(255,255,255,.5); }
.footer-cta-alt:hover { color: #fff; }

.footer-area {
  padding-block: clamp(44px, 5.5vw, 72px);
  border-bottom: 1px solid rgba(255,255,255,.12);
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(26px, 4vw, 60px); align-items: center;
}
@media (max-width: 820px) { .footer-area { grid-template-columns: 1fr; } }
.footer-area-head { display: flex; flex-direction: column; gap: 8px; }
.footer-area-head h3 {
  font-family: var(--font-head); font-weight: 700;
  font-size: clamp(22px, 2.4vw, 30px); color: var(--bg); letter-spacing: -0.01em;
}
.footer-area-list { display: flex; flex-wrap: wrap; gap: 10px; }
.area-chip {
  font-size: 14.5px; font-weight: 500; padding: 8px 15px;
  border-radius: 999px; white-space: nowrap;
  color: rgba(255,255,255,.86);
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.16);
  transition: border-color .18s, background .18s, color .18s;
}
.area-chip:hover { border-color: var(--accent-light); color: #fff; background: color-mix(in oklab, var(--accent-light) 16%, transparent); }
.footer-area-note { margin-top: 10px; color: rgba(255,255,255,.62); font-size: 15px; max-width: 44ch; }

.footer-main {
  padding-block: clamp(44px, 5.5vw, 68px);
  display: grid; grid-template-columns: 1.6fr 1fr 1.2fr;
  gap: clamp(28px, 4vw, 60px); border-bottom: 1px solid rgba(255,255,255,.1);
}
@media (max-width: 820px) { .footer-main { grid-template-columns: 1fr 1fr; } .footer-brand { grid-column: 1 / -1; } }
@media (max-width: 520px) { .footer-main { grid-template-columns: 1fr; } }
.footer-brand { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
/* Same wordmark, inheriting the footer's light-on-dark colour. */
.footer-brandmark { color: #fff; }
.footer-tag { font-size: 15px; line-height: 1.6; color: rgba(255,255,255,.62); max-width: 38ch; text-wrap: pretty; }
.footer-col { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.footer-col h4 {
  font-family: var(--font-head); font-size: 12px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: rgba(255,255,255,.5); margin-bottom: 4px;
}
.footer-col a {
  display: inline-flex; align-items: center; gap: 9px; font-size: 15.5px;
  color: rgba(255,255,255,.84); text-decoration: none; transition: color .15s;
}
.footer-col a svg { width: 16px; height: 16px; color: rgba(255,255,255,.45); flex: none; transition: color .15s; }
.footer-col a:hover svg { color: var(--accent-light); }
.footer-col a:hover { color: var(--accent-light); }
/* Matches the links above it in size and colour, but is not one — <address> is
   italic by default in the UA stylesheet, which would single it out. */
.footer-address {
  font-style: normal; font-size: 15.5px; line-height: 1.5;
  color: rgba(255,255,255,.84);
}
.footer-muted { font-size: 14px; color: rgba(255,255,255,.55); }
.footer-bottom {
  padding-block: 26px; display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 12px;
  font-size: 13.5px; color: rgba(255,255,255,.55);
}
.toplink { display: inline-flex; align-items: center; gap: 7px; color: inherit; text-decoration: none; font-weight: 500; transition: color .15s; }
.toplink svg { width: 15px; height: 15px; color: currentColor; }
.toplink:hover { color: #fff; }

/* ---------- inner-page fallback ---------- */
.prose { max-width: 68ch; margin-top: 28px; }
.prose > * + * { margin-top: 20px; }
.prose h2, .prose h3 { font-family: var(--font-head); font-weight: 600; }
.prose a { color: var(--accent); }

/* ---------- reveal on scroll ---------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- print (design proposal as PDF) ---------- */
@media print {
  .menu-btn, .mobile-nav, .lightbox, .skip-link { display: none !important; }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  @page { size: A4 portrait; margin: 11mm 9mm; }

  html, body { background: #fff !important; }
  .site-header { position: static !important; background: #111827 !important; border-bottom: none !important; }
  .hero--full .hero-stage { min-height: 0 !important; padding: 56px 0 64px !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .section { padding-block: 46px !important; }
  .svc, .step, form.lead, .cp, .section-head, .footer-cta, .hero-copy { break-inside: avoid; }
  .process, .contact, .site-footer { break-inside: avoid; }
  a[href]::after { content: "" !important; }
}
