/* Dynamic site – bastema (ärvt från Torrequebrada-designen).
   Färgvariablerna nedan är defaults; sajtens inställningar kan skriva över
   --sea/--sea-deep/--sun/--sand via en :root-injektion i SSR-layouten. */
:root {
  color-scheme: light dark;

  /* BAS-färgerna är de VALDA: temats, eller kundens override. De
     semantiska nedan härleds ur dem och är det CSS:en faktiskt använder.
     Uppdelningen finns för mörkt läge: där måste accenten ljusas upp för
     att synas mot mörk botten, och det går inte att räkna på en variabel
     som refererar sig själv. */
  --sand-base: #f6f1e7;
  --paper-base: #fffdf8;
  --ink-base: #23201b;
  --ink-2-base: #5b544a;
  --sea-base: #1f6f78;
  --sea-deep-base: #12484f;
  --sun-base: #d98a3d;
  --rule-base: #e6ddcd;

  --sand: var(--sand-base);
  --paper: var(--paper-base);
  --ink: var(--ink-base);
  --ink-2: var(--ink-2-base);
  --sea: var(--sea-base);
  --sea-deep: var(--sea-deep-base);
  --sun: var(--sun-base);
  --rule: var(--rule-base);
  /* Skuggan tonas i sajtens mörka färg. Den var hårdkodat turkos och
     låg under knapparna även på en sajt i brunt. */
  --shadow: 0 12px 40px -20px color-mix(in srgb, var(--sea-deep-base) 45%, transparent);
}

/* ---------------------------------------------------------------------
   Mörkt läge.

   Neutralerna byts mot fasta mörka toner — kundens ljusa bakgrundsfärg
   säger ingenting om hur en mörk sajt ska se ut. Accenterna DÄREMOT är
   kundens identitet och ska följa med, men en bränd sienna som fungerar
   mot grädde försvinner mot nästan svart. Därför ljusas de upp med
   color-mix, som behåller kulören men lyfter ljusheten.

   Två väljare, samma värden: media query för den som inte valt något
   (systemets inställning styr), attribut för den som klickat i
   sidhuvudet. :root:not([data-theme="light"]) gör att ett aktivt
   ljus-val vinner över systemets mörka läge.

   Hero-slöjan rörs INTE här. Varje tema uttrycker den i variabler som
   redan vänder (medelhav: color-mix på --sand), så en hårdkodad slöja
   hade kört över temats egen avsikt i stället för att följa den.

   Accenterna ljusas upp på två sätt. color-mix mot vitt fungerar i alla
   webbläsare som ritar sajten, men drar kulören mot grått: en bränd
   sienna blir dammig beige. oklch(from …) lyfter BARA ljusheten och
   behåller kulör och mättnad, alltså samma färg, läsbar mot mörkt. Den
   står i ett eget block under @supports längre ned.

   Förut stod de som två rader efter varandra, med tanken att en
   webbläsare utan relativ färgsyntax skulle hoppa över den andra. Det
   gör den inte för en variabel: värdet kontrolleras först när det
   används, så den andra raden vann alltid, och i äldre webbläsare
   (Chrome före 119, Safari före 16.4, Firefox före 128) blev --sea,
   --sea-deep och --sun ogiltiga i mörkt läge. Länkar, knappar och
   rubriker tappade sin färg.
   ------------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --sand: #16130f;
    --paper: #1e1a15;
    --ink: #ece5da;
    --ink-2: #a89e91;
    --rule: #332c24;
    --sea: color-mix(in oklab, var(--sea-base), #fff 40%);
    --sea-deep: color-mix(in oklab, var(--sea-base), #fff 66%);
    --sun: color-mix(in oklab, var(--sun-base), #fff 26%);
    --shadow: 0 14px 44px -22px rgba(0, 0, 0, .8);
  }
}
:root[data-theme="dark"] {
  --sand: #16130f;
  --paper: #1e1a15;
  --ink: #ece5da;
  --ink-2: #a89e91;
  --rule: #332c24;
  --sea: color-mix(in oklab, var(--sea-base), #fff 40%);
  --sea-deep: color-mix(in oklab, var(--sea-base), #fff 66%);
  --sun: color-mix(in oklab, var(--sun-base), #fff 26%);
  --shadow: 0 14px 44px -22px rgba(0, 0, 0, .8);
}
/* Samma två väljare, med relativ färgsyntax där webbläsaren kan den.
   Blocket står efter de ovan och vinner på ordningen. */
@supports (color: oklch(from red l c h)) {
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --sea: oklch(from var(--sea-base) 0.78 c h);
      --sea-deep: oklch(from var(--sea-base) 0.86 c h);
      --sun: oklch(from var(--sun-base) 0.82 c h);
    }
  }
  :root[data-theme="dark"] {
    --sea: oklch(from var(--sea-base) 0.78 c h);
    --sea-deep: oklch(from var(--sea-base) 0.86 c h);
    --sun: oklch(from var(--sun-base) 0.82 c h);
  }
}

/* ---------------------------------------------------------------------
   Text i sajtens färger.

   Överrader, kortens etiketter och titlar, länkar, aktiv menypunkt och
   rubriker står i sajtens egna färger, och kunden kan välja vilken färg
   som helst i admin. Prompten ber om färger med kontrast, men det går
   inte att lita på: en ljus --sun (#f2a93b) gav Norrs överrad 2,0:1 mot
   papperet, och Klassisks egen --sun gav korttitlarna 2,4:1 mot sanden.
   All text i sajtens färger tar därför färgen från variablerna nedan,
   som räknar fram en färg de vet håller.

   Samma grepp som knapparnas tak (.cta): färgen tas till XYZ, där y är
   den relativa luminansen som WCAG räknar kontrast på, och x, y och z
   flyttas lika mycket. Kulören är kvar, bara ljusheten ändras. En färg
   som redan håller rörs inte.

   Ljust läge: ett tak. Luminansen sänks till högst ett tal per variabel,
   valt efter den mörkaste botten texten står på:
   - --sun-text 0,147: minst 4,5:1 mot en sand med luminans 0,84
     (#f7ebd6, Ugnsluckans) eller ljusare, och mot varje temas papper.
   - --sea-text och --sea-deep-text 0,125: kortens etiketter står på en
     ton av --sea själv, och en mättad ton mörkar papperet mer än sanden
     är mörk. Med 0,147 fick en röd etikett 4,1:1, med 0,125 minst 4,55:1
     för varje färg. --sea-deep är mörk i varje rimlig palett (prompten
     kräver 7:1), så taket kostar inget där och ger marginal för
     Medelhavs spökknapp på heron.
   - --sun-text-large 0,245: 3:1 mot samma sand, för stor text:
     Medelhavs handskrivna överrad och korttitlar.
   Temanas egna färger och genererade paletter ligger under taken och
   ritas som förut, utom där de inte höll. Nära taket flyttas en färg
   lite: Norrs rost (luminans 0,156) går från #b0532e till #ab512d, och
   Klassisks turkos (0,130) en nyans, från #1f6f78 till #1e6d76.

   Mörkt läge: ett golv. Accenterna är redan upplyfta (oklch ovan) och
   har minst luminans 0,29 (rent rött, det mörkaste fallet). Golvet
   blandar in vitt i linjärt ljus tills luminansen är minst 0,3, vilket
   ger minst 5,7:1 mot den mörka sidan. Det är ett skyddsnät för en accent
   som någon gång blir mörkare än så.

   Ett uttryck för båda lägena. --dark är 0 i ljust läge och 1 i mörkt:
   i ljust läge blir golvet 0 och gör ingenting, i mörkt läge blir taket
   större än 1 och gör ingenting. Svart och vitt ger division med noll,
   och oändligheten tas om hand av min() och max().

   Reserven, för en webbläsare utan relativ färgsyntax, kan inte räkna per
   färg. Den drar färgen halvvägs mot svart i ljust läge och mot vitt i
   mörkt (--text-end), i oklab. Det håller för vilken färg som helst: vitt
   blir luminans 0,125 i ljust läge och svart 0,25 i mörkt (4,9:1). Priset
   är mörkare accenter i ljust läge i de webbläsarna. Taken, golvet och
   reserven testas i theme_text_css_test.go. */
:root {
  --dark: 0;
  --text-end: #000;
  --sun-text: color-mix(in oklab, var(--sun) 50%, var(--text-end));
  --sun-text-large: color-mix(in oklab, var(--sun) 50%, var(--text-end));
  --sea-text: color-mix(in oklab, var(--sea) 50%, var(--text-end));
  --sea-deep-text: color-mix(in oklab, var(--sea-deep) 50%, var(--text-end));
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --dark: 1; --text-end: #fff; }
}
:root[data-theme="dark"] { --dark: 1; --text-end: #fff; }
@supports (color: color(from red xyz calc(x * min(1, .5 / y)) y z)) {
  :root {
    --sun-text: color(from var(--sun) xyz
      calc(x * min(1, .147 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .147 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .147 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sun-text-large: color(from var(--sun) xyz
      calc(x * min(1, .245 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .245 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .245 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sea-text: color(from var(--sea) xyz
      calc(x * min(1, .125 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .125 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .125 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sea-deep-text: color(from var(--sea-deep) xyz
      calc(x * min(1, .125 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .125 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .125 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
  }
}

/* ---------------------------------------------------------------------
   Ytor i sajtens färger.

   Knapparna, initialen i sidhuvudet, det aktiva språket, checklistans
   ruta och knapparnas hoverläge är ytor i sajtens färger med text på.
   Kunden väljer färgerna fritt i admin, och bara knapparna hade ett tak.
   Uppmätt 2026-09-29: initialen 1,7:1 med en ljus --sea (#9ad0d6),
   Medelhavs initial 3,7:1 med temats egen terrakotta, och checklistans
   vita bock 2:1 i mörkt läge med alla färger, eftersom accenten ljusas
   upp där.

   Ytorna tar därför färgen från variablerna nedan, med samma uttryck som
   textfärgerna ovan: ett tak i ljust läge, ett golv i mörkt, och en färg
   som redan håller rörs inte. Texten på dem är --paper, som vänder med
   läget: nästan vit i ljust läge, nästan svart i mörkt.
   - Ljust läge: luminansen högst 0,16, knapparnas tak sedan tidigare.
     Mot varje temas papper minst 4,8:1.
   - Mörkt läge: minst 0,3, som textfärgernas golv. Mot det mörka
     papperet minst 5,7:1. De upplyfta accenterna ligger redan över
     (minst 0,29, rent rött), så golvet är ett skyddsnät.
   Mörkt läge behåller alltså den ljusa accenten med mörk text, som
   knapparna redan hade, i stället för att mörka ytan: en mörk yta hade
   försvunnit mot den mörka sidan.

   Reserven utan relativ färgsyntax är textfärgernas: färgen halvvägs mot
   svart i ljust läge och mot vitt i mörkt. Den håller för vilken färg som
   helst (högst 0,125 respektive minst 0,25, 4,9:1). Priset är mörkare
   knappar och ytor i de webbläsarna, också med temats egna färger.

   --sea-dark och --sea-deep-dark är ytor som är mörka i BÅDA lägena, med
   ljus text: Medelhavs sidfot, och herons slöja, band och bildtexter. De
   utgår från BAS-färgerna, som inte ljusas upp i mörkt läge, och har bara
   ett tak.
   - --sea-dark 0,135: Medelhavs gräddvita sidfotstext minst 4,7:1.
     Klassisks turkos (0,130) ligger under och ritas som förut i herons
     glöd, Medelhavs blå (0,168) blir en nyans mörkare i sidfoten.
   - --sea-deep-dark 0,055: strax över Klassisks mörka turkos (0,053),
     så att slöjan över ett foto aldrig blir ljusare än med temats egen
     färg. Temanas, livesajternas och de genererade paletternas mörka
     färger ligger under. Värsta fallet i Klassisks hero utan foto,
     överraden rakt under glöden med båda färgerna vid taken, ger minst
     4,9:1 räknat (4,85:1 uppmätt med vit accent och en ljus "Mörk").
     Promptens regel (7:1 mot sanden) tillåter något ljusare, och en
     sådan färg ritas en aning mörkare som yta; som rubrik är den orörd.
   Utan relativ färgsyntax gäller BAS-färgen rakt av, som före taken, och
   inte en reserv som håller för vilken färg som helst. En sådan hade
   dragit varje färg lika långt mot svart, och på de här stora ytorna
   blev herons slöja och Medelhavs sidfot nästan svarta i sajtens kulör,
   också med temats egna färger. Risken som tas: en ljus "Mörk" eller
   accent vald i admin, i en webbläsare utan relativ färgsyntax (Chrome
   före 119, Safari före 16.4, Firefox före 128). Och Medelhavs egen blå
   sidfot, som där har 4,0:1 (3,1:1 med de ljusa prickarna förut).

   Taken, golven och reserverna räknas i theme_fill_css_test.go. */
:root {
  --sun-fill: color-mix(in oklab, var(--sun) 50%, var(--text-end));
  --sea-fill: color-mix(in oklab, var(--sea) 50%, var(--text-end));
  --sea-deep-fill: color-mix(in oklab, var(--sea-deep) 50%, var(--text-end));
  --sea-dark: color-mix(in oklab, var(--sea-base) 90%, #000);
  --sea-deep-dark: var(--sea-deep-base);
}
@supports (color: color(from red xyz calc(x * min(1, .5 / y)) y z)) {
  :root {
    --sun-fill: color(from var(--sun) xyz
      calc(x * min(1, .16 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .16 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .16 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sea-fill: color(from var(--sea) xyz
      calc(x * min(1, .16 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .16 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .16 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sea-deep-fill: color(from var(--sea-deep) xyz
      calc(x * min(1, .16 / y + var(--dark)) + (.9505 - x) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(y * min(1, .16 / y + var(--dark)) + (1 - y) * max(0, (.3 * var(--dark) - y) / (1 - y)))
      calc(z * min(1, .16 / y + var(--dark)) + (1.0891 - z) * max(0, (.3 * var(--dark) - y) / (1 - y))));
    --sea-dark: color(from var(--sea-base) xyz
      calc(x * min(1, .135 / y)) calc(y * min(1, .135 / y)) calc(z * min(1, .135 / y)));
    --sea-deep-dark: color(from var(--sea-deep-base) xyz
      calc(x * min(1, .055 / y)) calc(y * min(1, .055 / y)) calc(z * min(1, .055 / y)));
  }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--sand);
  line-height: 1.6;
}
.wrap { width: min(1100px, 92%); margin: 0 auto; }
h1, h2, h3 { font-family: Georgia, "Times New Roman", serif; letter-spacing: -0.02em; line-height: 1.1; }
a { color: inherit; }

/* Textfärg-klasser (enum – saneraren tillåter endast dessa i rik text) */
.c-sea { color: var(--sea-text); }
.c-sun { color: var(--sun-text); }
.c-sea-deep { color: var(--sea-deep-text); }
.c-ink-2 { color: var(--ink-2); }

/* Masthead */
.masthead {
  position: sticky; top: 0; z-index: 10;
  /* Härledd ur --paper, inte hårdkodad: i mörkt läge blev sidhuvudet
     annars en vit list över en mörk sajt. */
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.masthead .wrap { display: flex; align-items: center; justify-content: space-between; padding: .9rem 0; }
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; font-weight: 600; }
/* Initialen i en cirkel när sajten saknar logotyp. flex: none: på en
   smal skärm trycktes cirkeln annars ihop till en oval när namnet
   behövde platsen. Cirkeln är en yta i sajtens färg (--sea-fill, se
   Ytor i sajtens färger): med en ljus --sea fick initialen 1,7:1. */
.brand .mark {
  display: grid; place-items: center; flex: none;
  width: 2.1rem; height: 2.1rem; border-radius: 50%;
  background: var(--sea-fill); color: var(--paper); font-family: Georgia, serif; font-size: .95rem;
}
.brand .word { font-size: 1.05rem; }
nav a { margin-left: 1.4rem; text-decoration: none; color: var(--ink-2); font-size: .95rem; }
nav a:hover, nav a.active { color: var(--sea-text); }

/* ---------------------------------------------------------------------
   Mobilmenyn (layout.html.tmpl).

   Bred skärm: behållaren .site-menu ritar ingen egen låda, så menyn och
   språkväxlaren är led i sidhuvudets rad precis som förut, och knappen
   syns inte. Författarens display vinner över webbläsarens
   display:none för en stängd popover.

   Smal skärm: knappen öppnar behållaren som en popover. Det kräver inget
   skript, och Esc och klick utanför stänger den. Allt som hör till den
   står under @supports: en webbläsare utan popover får ingen död knapp,
   utan menyn som en rad under namnet, där den går att nå.

   Brytpunkten ligger så att en stående surfplatta också får knappen. En
   meny på fem sex sidor och en språkväxlare får inte plats bredvid namnet
   där, och radbrytningen var det som fick menyn att krocka med namnet.
   ------------------------------------------------------------------ */
.site-menu { display: contents; color: inherit; }
.menu-toggle { display: none; }

@media (max-width: 56rem) {
  .masthead .wrap { flex-wrap: wrap; gap: .5rem .75rem; padding: .7rem 0; }
  /* Namnet får ta den plats som finns och bryta rad, men aldrig trycka
     knapparna ut över kanten. */
  .brand { flex: 0 1 auto; min-width: 0; margin-right: auto; }
  /* Namnet bryts bara mellan ord. Förut fick det brytas var som helst
     (overflow-wrap: anywhere), och vid 320 bred stod det "Ugnsluck" på
     en rad och "an Bageri" på nästa. Ett ord som ensamt är bredare än
     platsen kortas med en ellips i stället för att delas; hela namnet
     finns kvar för skärmläsare och i sidfoten. */
  .brand .word {
    line-height: 1.2;
    overflow-wrap: normal; word-break: normal; hyphens: manual;
    overflow: hidden; text-overflow: ellipsis;
  }
  /* Reserven utan popover: menyn på en egen rad sist i sidhuvudet, och
     en menypunkt bryts aldrig mitt i. */
  .site-menu { display: block; order: 1; flex-basis: 100%; }
  .site-menu nav { display: flex; flex-wrap: wrap; gap: .15rem 1.1rem; }
  .site-menu nav a { margin-left: 0; white-space: nowrap; }
  .site-menu .langs { margin-top: .4rem; }

  @supports selector(:popover-open) {
    .masthead .wrap { flex-wrap: nowrap; }
    .menu-toggle {
      display: inline-flex; align-items: center; gap: .4rem; flex: none;
      height: 2.25rem; padding: 0 .85rem 0 .7rem;
      border: 1px solid var(--rule); border-radius: 999px;
      background: transparent; color: var(--ink);
      font: inherit; font-size: .9rem; font-weight: 600; line-height: 1;
      cursor: pointer;
      transition: color .15s, border-color .15s;
    }
    .menu-toggle:hover { color: var(--sea-text); border-color: var(--sea); }
    .menu-toggle:focus-visible {
      outline: none; border-color: var(--sea);
      box-shadow: 0 0 0 3px color-mix(in oklab, var(--sea) 25%, transparent);
    }
    .menu-toggle svg { display: block; flex: none; }
    /* Ikonen visar läget: tre streck när menyn är stängd, ett kryss när
       den är öppen. Namnet är detsamma i båda lägena; läget läses upp som
       expanderat eller komprimerat. */
    .menu-toggle .i-close { display: none; }
    .menu-toggle:has(+ .site-menu:popover-open) .i-menu { display: none; }
    .menu-toggle:has(+ .site-menu:popover-open) .i-close { display: block; }
    .masthead .theme-toggle { flex: none; margin-left: 0; }

    .site-menu:not(:popover-open) { display: none; }
    /* Panelen ligger i webbläsarens översta lager, utanför sidhuvudet,
       och placeras därför med fast position. public.js sätter --menu-top
       till sidhuvudets underkant när menyn öppnas; utan skript gäller
       reserven, som är sidhuvudets höjd med ett namn på en rad. */
    .site-menu:popover-open {
      display: block;
      position: fixed; inset: var(--menu-top, calc(3.65rem + 1px)) 0 auto 0;
      width: auto; height: auto; margin: 0;
      max-height: calc(100dvh - var(--menu-top, calc(3.65rem + 1px)));
      overflow: auto; overscroll-behavior: contain;
      padding: .3rem 4% 1.3rem;
      border: 0; border-bottom: 1px solid var(--rule);
      background: var(--paper); color: var(--ink);
      box-shadow: 0 22px 40px -26px rgba(0, 0, 0, .5);
    }
    .site-menu:popover-open nav { display: block; }
    .site-menu:popover-open nav a {
      display: block; margin: 0; padding: .85rem .1rem; white-space: normal;
      border-bottom: 1px solid var(--rule);
      color: var(--ink); font-size: 1.05rem;
    }
    .site-menu:popover-open nav a:hover,
    .site-menu:popover-open nav a.active { color: var(--sea-text); }
    .site-menu:popover-open nav a:focus-visible {
      outline: 2px solid var(--sea); outline-offset: -2px; border-radius: 4px;
    }
    /* Språkväxlaren under menyn, med ytor stora nog för ett finger. */
    .site-menu:popover-open .langs { margin: 1rem 0 0; gap: .4rem; flex-wrap: wrap; }
    .site-menu:popover-open .langs a {
      font-size: .85rem; padding: .6rem .85rem;
      border: 1px solid var(--rule);
    }
    /* Kanten i ytans färg: samma yta, inte en ram runt den. */
    .site-menu:popover-open .langs a.active { border-color: var(--sea-fill); }
  }
}
/* Mycket smal skärm (till 384 bred): sidhuvudet tätare och namnet en
   aning mindre, så att ett vanligt namn på två ord får plats hela. Vid
   320 bred fick namnet annars runt 100 px bredvid initialen, menyknappen
   och temaknappen, och redan "Ugnsluckan" är bredare än så. */
@media (max-width: 24rem) {
  .masthead .wrap { column-gap: .5rem; }
  .brand { gap: .45rem; }
  .brand .word { font-size: .95rem; }
  .menu-toggle { padding: 0 .6rem 0 .5rem; gap: .3rem; }
}

/* Hero.
   Allt härleds ur sajtens egna färger. Slöjan var hårdkodat turkos, så en
   chokladbutik i brunt fick en blågrön hero.

   BAS-färgen, inte --sea-deep: den semantiska ljusas upp i mörkt läge
   för att synas som text mot mörk botten, och som slöja hade den blivit
   en ljus yta under vit herotext. Den valda mörka färgen bär vit text i
   båda lägena (promptens färgregler: minst 7:1 mot sanden), och
   täckningen är densamma som den turkosa hade, så kontrasten mot vit text
   är minst lika god som förut. Glöden uppe till höger är accenten, något
   ljusare.

   Båda går genom taken för mörka ytor, --sea-deep-dark och --sea-dark
   (se Ytor i sajtens färger). Temats färger och de genererade
   paletternas ligger under dem och ritas som förut. Men färgerna går att
   sätta till vad som helst i admin. Uppmätt före taken: med en ljus
   "Mörk" (#6fa8dc) fick överraden 1,8:1, och med vit som accent låg
   glöden ljus bakom den, 3,4:1 på en telefon. */
.hero {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--sea-deep-dark) 72%, transparent),
      color-mix(in srgb, var(--sea-deep-dark) 55%, transparent)),
    radial-gradient(120% 120% at 80% 0%,
      color-mix(in oklab, var(--sea-dark), #fff 12%) 0%,
      var(--sea-deep-dark) 60%,
      color-mix(in oklab, var(--sea-deep-dark), #000 25%) 100%);
  color: #fff;
  padding: 6rem 0 5rem;
}
/* Foto-hero: valfri bakgrundsbild med tema-styrd gradient-slöja. Bilden
   kommer via --hero-photo (style-attr från SSR, strikt uuid-byggd URL);
   slöjans ton/täthet sätts per tema via variablerna nedan. Klassisk = mörk
   slöja i sajtens mörka färg (vit herotext), ljusa teman overridar med
   ljus slöja.

   --hero-band är bakgrunden under texten på smal skärm (se nedan). Den
   ska bära herons text i temat utan slöja: här sajtens mörka BAS-färg
   under vit text, i Norr papperet under bläcktext. Den mörka färgen är,
   här och i slöjan, --sea-deep-dark: BAS-färgen genom taket för mörka
   ytor, så att bandet håller också när "Mörk" är ljus.

   Bred skärm: slöjan är två lager. Det lodräta täcker hela fotot och
   bär rubriken, som är stor text (3:1) och får gå över hela bredden. Det
   vågräta, --hero-veil-col, ligger bara bakom textspalten till vänster,
   där överraden, ingressen och knapparna står, och tunnas ut mot höger.
   Där syns fotot som förut.

   Förut fanns bara det lodräta, och det är tunnast överst, där
   överraden står. Uppmätt 2026-09-29 mot det mest ogynnsamma under
   varje textrad, 1024 och 1440 bred, ljust och mörkt läge, över
   surdegsbrödet, ett nästan vitt och ett nästan svart foto, med temats
   färger, provsajtens och tre genererade paletter: i Klassisk hade
   överraden ned till 2,7:1 och ingressen 4,3:1, i Norr överraden ned
   till 1,8:1 och ingressen 3,4:1. Med spalten minst 5,3:1 för
   överraden och 6,1:1 för ingressen i båda temana.

   Spalten är ingressens bredd (40rem) från .wrap:s vänsterkant, som är
   4 % eller mitten minus 550px. Överraden hålls inom den på bred skärm;
   en lång överrad stack annars ut där slöjan tunnas ut. */
:root {
  --hero-veil-top: color-mix(in srgb, var(--sea-deep-dark) 58%, transparent);
  --hero-veil-bottom: color-mix(in srgb, var(--sea-deep-dark) 88%, transparent);
  --hero-veil-col: color-mix(in srgb, var(--sea-deep-dark) 65%, transparent);
  --hero-band: var(--sea-deep-dark);
}
/* Fotot beskärs kring mitten, både här och i bandet på smal skärm. */
.hero.has-photo {
  --hero-col: calc(max(4%, 50% - 550px) + 40rem);
  background-image:
    linear-gradient(90deg,
      var(--hero-veil-col) var(--hero-col),
      transparent calc(var(--hero-col) + 24%)),
    linear-gradient(180deg, var(--hero-veil-top), var(--hero-veil-bottom)),
    var(--hero-photo);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
@media (min-width: 48.01rem) {
  .hero.has-photo .eyebrow { max-width: 40rem; }
}
/* Smal skärm: fotot står som ett eget band överst i heron, och texten
   under det på en hel färg. Ingen slöja behövs.

   Förut låg texten ovanpå fotot här också. På en telefon fyller texten
   nästan hela heron, så slöjan fick vara tät överallt, och fotot syntes
   bara som en mörk skugga. Heron är dessutom smal och hög där, så fotot
   skalades efter höjden: det enda som syntes klart var överkanten. På
   provsajten var det en köksmaskin ovanför surdegsbrödet. Nu är bandet
   16:10 och beskärs kring mitten, och texten står på en hel färg, så
   kontrasten beror inte på vad fotot föreställer.

   max-height: en telefon på tvären är bredare än den är hög, och ett
   16:10-band hade fyllt hela skärmen och tryckt ned rubriken under
   kanten. Med knappt halva höjden syns rubriken fortfarande. width:
   100% håller bandet kant till kant när taket slår till; annars krymper
   webbläsaren bredden för att behålla proportionen.

   Bandet tar thumben (max 1200 px). Heron går kant till kant, så
   fullstorleken behövs på stora skärmar, men en telefon som ritar den
   400 px bred ska inte ladda ned en halv megabyte för det. Saknas
   --hero-photo-sm (äldre sajt) används fullstorleken.

   Regeln står EFTER basregeln, och ett tema som lägger en egen slöja på
   .hero.has-photo måste ta bort den här på samma sätt (se Medelhav). */
@media (max-width: 48rem) {
  .hero.has-photo {
    padding-top: 0;
    background: var(--hero-band);
  }
  .hero.has-photo::before {
    content: "";
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    max-height: 45vh;
    margin-bottom: 2.5rem;
    background: var(--hero-photo-sm, var(--hero-photo)) center / cover no-repeat;
  }
}

/* Överraden och ingressen är ljusa toner av sajtens egna färger, inte
   fasta: persika och turkosvitt passade bara standardpaletten.

   Överraden är en ton av --sun, och tonen blir bara så ljus som färgen
   är. Med en mörk --sun (#5a2a10) fick den 3,7:1 mot slöjan över ett
   nästan vitt foto, där slöjan släpper igenom mest (luminans 0,098).
   Därför lyfts tonen till luminans minst 0,62, vilket ger 4,5:1 där.
   Vitt blandas in i linjärt ljus, som golvet för textfärgerna ovan, och
   en ton som redan är ljusare rörs inte: temats och de genererade
   paletternas toner ligger på 0,59 och uppåt, och ritas som förut eller
   nästan.

   Utan relativ färgsyntax en tunnare ton, 14 % av färgen, som är ljus
   nog (minst 0,63) vilken färg sajten än har. */
.hero .eyebrow {
  text-transform: uppercase; letter-spacing: .22em; font-size: .72rem;
  color: color-mix(in oklab, var(--sun-base) 14%, #fff); margin: 0 0 1rem;
}
@supports (color: color(from red xyz calc(x * min(1, .5 / y)) y z)) {
  .hero .eyebrow {
    color: color(from color-mix(in oklab, var(--sun-base) 32%, #fff) xyz
      calc(x + (.9505 - x) * max(0, (.62 - y) / (1 - y)))
      calc(y + (1 - y) * max(0, (.62 - y) / (1 - y)))
      calc(z + (1.0891 - z) * max(0, (.62 - y) / (1 - y))));
  }
}
/* Ett långt sammansatt ord ("kardemummabullar") är bredare än en telefon
   i herons storlek och stack ut över högerkanten, så att hela sidan gick
   att skjuta i sidled. Nu avstavas långa ord där webbläsaren kan språket,
   och ett ord som ändå inte får plats bryts där raden tar slut.
   hyphenate-limit-chars: bara ord på minst 12 tecken, med minst 5 på
   var sida, så att en rubrik inte blir hackig av avstavade kortord. */
.hero h1 {
  font-size: clamp(2.4rem, 6vw, 4rem); margin: 0 0 1rem;
  overflow-wrap: break-word; hyphens: auto; hyphenate-limit-chars: 12 5 5;
}
.hero .lede { max-width: 40rem; font-size: 1.15rem; color: color-mix(in srgb, #fff 90%, var(--sea-deep-base)); }
.hero-actions { margin-top: 2rem; display: flex; gap: .8rem; flex-wrap: wrap; }
/* Knappens text är --paper, som vänder med bakgrunden. --sun är en
   mättad mellanton i ljust läge (vit text, se promptens färgregler) men
   ljusas upp i mörkt läge; med fast vit text blev knappen vitt på ljust.
   --paper är nästan vitt i ljust läge och nästan svart i mörkt.
   Spökknappen står på herons mörka slöja i båda lägena och behåller vitt. */
/* Knappens bakgrund får aldrig vara så ljus att texten inte går att läsa.

   Temats egen --sun (#d98a3d) gav 2,7:1 mot den ljusa texten. Promptens
   krav (vit text på sun minst 4,5:1) räcker inte heller helt, eftersom
   texten är --paper, en aning mörkare än vitt, och kunden kan välja
   vilken färg som helst i admin. Så i stället för att lita på färgen
   räknar knappen fram en färg den vet håller: --sun-fill (se Ytor i
   sajtens färger).

   color(from … xyz …) ger färgen i XYZ, där y är den relativa luminansen,
   samma tal som WCAG räknar kontrast på. x, y och z multipliceras med
   samma faktor, högst 1, så att y blir högst 0,16. Det är samma sak som
   att blanda färgen mot svart i linjärt ljus: kulören är kvar, bara
   ljusheten sänks. En färg som redan är mörk nog rörs inte (faktorn blir
   1). Kontrasten mot varje temas --paper blir minst 4,8:1 räknat och
   4,7:1 uppmätt (skärmen avrundar färgen till 8 bitar), vilken färg
   kunden än valt. I mörkt läge är --sun ljus och texten mörk, och där
   gäller golvet i stället.

   Förut fick en webbläsare utan relativ färgsyntax --sun rakt av, och
   temats egen --sun gav 2,7:1 där. Nu får den ytornas reserv. */
.cta {
  display: inline-block; padding: .8rem 1.5rem; border-radius: 999px;
  background: var(--sun-fill); color: var(--paper); text-decoration: none; font-weight: 600;
  box-shadow: var(--shadow); transition: transform .15s ease;
}
.cta:hover { transform: translateY(-2px); }
.cta.ghost { background: transparent; color: #fff; border: 1px solid rgba(255,255,255,.6); box-shadow: none; }

/* Språkväxlare i masthead – diskret pill-rad, ärver temats färger. */
.langs { display: flex; gap: .15rem; align-items: center; }
.langs a {
  font-size: .74rem; font-weight: 700; letter-spacing: .06em;
  color: var(--ink-2); text-decoration: none;
  padding: .2rem .45rem; border-radius: 999px; line-height: 1;
}
.langs a:hover { color: var(--sea-text); background: color-mix(in srgb, var(--sea) 10%, transparent); }
/* --paper och inte vitt: --sea ljusas upp i mörkt läge, och vit text på
   den blev oläslig. Ytan är --sea-fill: med --sea rakt av gav en ljus
   accent det aktiva språket samma kontrast som initialen, 1,7:1. */
.langs a.active { color: var(--paper); background: var(--sea-fill); }

/* Logotyp i mastheaden. Ersätter initialcirkeln när kunden laddat upp
   en, och visas hel: i sina egna proportioner, utan cirkel och utan
   ruta bakom. Förut ärvde den initialens border-radius: 50%, och ett
   brett ordmärke klipptes till en oval där halva namnet saknades.

   Höjden är fast och bredden följer bildens proportioner (width och
   height i layouten är bildens egna mått), med ett tak. Ett ordmärke,
   eller en logotyp vars mått inte är kända, får krympa på en smal skärm:
   object-fit: contain ritar den då mindre men hel, aldrig avhuggen. En
   rund eller hög logotyp är redan smal och krymper inte. Temana rör inte
   logotypen, bara initialen. */
.brand .mark.logo {
  display: block; flex: none;
  width: auto; height: 2.5rem; max-width: 10rem;
  border-radius: 0; background: none;
  object-fit: contain; object-position: left center;
}
.brand.logo-wide .mark.logo,
.brand .mark.logo:not([width]) { flex: 0 1 auto; min-width: 0; }
@media (max-width: 56rem) {
  /* Samma höjd som menyknappen, så att raden inte blir högre. */
  .brand .mark.logo { height: 2.25rem; max-width: min(10rem, 48vw); }
  /* Namnet bredvid logotypen får aldrig så lite plats att nästan inget
     av det syns. */
  .brand .word { min-width: min(6rem, 26vw); }
  /* En bred logotyp krymper i stället för att ta namnets plats. Namnet
     döljs inte: en bred bild är lika ofta ett foto som ett ordmärke, och
     Kalles slakteri (ett foto från slakteriet som logotyp) visade då bara
     bilden i sidhuvudet. Hellre namnet två gånger än inte alls. */
  .brand.logo-wide .mark.logo { max-width: min(6.5rem, 30vw); }
  /* Namnet går före logotypen. Förut krympte de i proportion till sina
     bredder, och ett namn på två ord är bredare än logotypen, så namnet
     trycktes ned till sin minsta bredd och kortades medan logotypen
     fortfarande hade plats kvar. Nu utgår logotypen från noll och växer
     in i det som blir över när namnet fått sitt, men aldrig smalare än
     en ikon. */
  .brand.logo-wide .mark.logo,
  .brand .mark.logo:not([width]) { flex: 1 1 0; min-width: 2.5rem; }
}

/* Sektioner. Varje block renderas som en egen section — utan justering
   dubbleras avståndet (3+3rem) mellan alla block. Regeln: ett block bär
   sitt eget avstånd NEDÅT, efterföljande block börjar tätt. Rubrikblock
   hör ihop med blocket efter sig: stor luft före rubriken, liten efter. */
.section { padding: 3rem 0; }
.section + .section { padding-top: 0; }
.section.section-heading { padding-bottom: 1.1rem; }
.section-head { max-width: 42rem; }
.section-head h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); margin: 0 0 .6rem; color: var(--sea-deep-text); }
.section-head p { color: var(--ink-2); font-size: 1.05rem; margin: 0; }

/* Rik text */
.prose { max-width: 46rem; font-size: 1rem; }
.prose h2, .prose h3 { color: var(--sea-deep-text); margin: 1.4rem 0 .5rem; }
.prose a { color: var(--sea-text); }
.prose blockquote {
  margin: 1rem 0; padding: .4rem 0 .4rem 1.1rem;
  border-left: 3px solid var(--sun); color: var(--ink-2);
}

/* Kort */
.cluster { margin-top: 1rem; }
.cluster-title {
  font-size: 1.1rem; color: var(--sun-text); margin: 0 0 1.1rem;
  display: flex; align-items: center; gap: .7rem;
  text-transform: uppercase; letter-spacing: .1em; font-family: inherit; font-weight: 700;
}
.cluster-title::before { content: ""; width: 1.8rem; height: 2px; background: var(--sun); }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.2rem; }
.cards article {
  background: var(--paper); border: 1px solid var(--rule); border-radius: 14px;
  padding: 1.5rem; box-shadow: 0 6px 24px -18px color-mix(in srgb, var(--sea-deep) 40%, transparent);
  transition: transform .15s ease, box-shadow .15s ease;
  overflow: hidden; /* miniatyrbilden klipps av kortets hörnradie (temaföljsamt) */
}
/* Miniatyrbild i kort: kant-till-kant upptill, klick öppnar lightbox (public.js). */
.card-photo { display: block; margin: -1.5rem -1.5rem 1rem; cursor: zoom-in; }
/* aspect-ratio, inte fast höjd: korten är mellan 260 och ~540 px breda,
   och 150 px blev en tunn remsa på de breda. Proportionen håller sig
   oavsett bredd, och object-fit:cover gör att vilket foto som helst kan
   läggas in utan att bli utdraget. */
.card-photo img {
  width: 100%; aspect-ratio: 16 / 10; height: auto;
  object-fit: cover; display: block;
}
.cards article:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.pin {
  display: inline-block; font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  /* Följer accenten. Var hårdkodat turkos, så en kund med terrakotta
     fick turkosa etiketter — och i mörkt läge en ljus plupp. */
  text-transform: uppercase; color: var(--sea-text);
  background: color-mix(in srgb, var(--sea) 14%, transparent);
  padding: .25rem .6rem; border-radius: 999px; margin-bottom: .8rem;
}
.cards h3 { font-size: 1.2rem; margin: 0 0 .5rem; }
.cards p { margin: 0 0 .4rem; color: var(--ink-2); font-size: .96rem; }

/* Checklistor (ul.checklist ur rik text): boxar i CSS, avbockningsbara –
   public.js togglar li.checked och minns valet i localStorage.

   Rutan är en yta i sajtens färg (--sea-fill) och bocken --paper, som
   knapparnas text. Förut var bocken fast vit på --sea: i mörkt läge, där
   accenten ljusas upp, 2:1 med alla färger, och i ljust läge 1,7:1 med en
   ljus accent. Kanten har rutans färg, också avbockad, så att rutan syns
   mot papperet också när --sea är ljus. */
.checklist { list-style:none; padding-left:.2rem; }
.checklist li { position:relative; padding-left:1.8rem; cursor:pointer; }
.checklist li::before {
  content:""; position:absolute; left:.15rem; top:.3em;
  width:.95em; height:.95em; border:2px solid var(--sea-fill);
  border-radius:4px; background:var(--paper);
}
.checklist li.checked::before { background:var(--sea-fill); }
.checklist li.checked::after {
  content:"✓"; position:absolute; left:.38rem; top:.32em;
  color:var(--paper); font-size:.75em; font-weight:700; line-height:1.1;
}
.checklist li.checked { color:var(--ink-2); }

/* Bildgalleri: kollage på 6-kolumnsraster. Varje bild spänner kolumner/rader
   efter vald storlek (s/m/l) och dense-flödet packar igen hålen. */
.gallery {
  display: grid; grid-template-columns: repeat(6, 1fr);
  grid-auto-flow: dense;
  /* Rad + mellanrum i cqw → cellernas proportioner är konstanta oavsett
     containerbredd (admin-editorns miniraster använder samma kvoter =
     WYSIWYG). px-raderna är fallback för browsers utan container queries.
     8.18cqw ≈ 90px och 1.45cqw ≈ 16px vid 1100px innehållsbredd. */
  gap: 1rem; grid-auto-rows: 90px;
  gap: 1.45cqw; grid-auto-rows: 8.18cqw;
}
.section { container-type: inline-size; }
.gallery figure {
  margin: 0; position: relative; overflow: hidden; border-radius: 12px;
  border: 1px solid var(--rule); background: var(--paper);
}
.gallery .sz-s { grid-column: span 2; grid-row: span 2; }
.gallery .sz-m { grid-column: span 3; grid-row: span 3; }
.gallery .sz-l { grid-column: span 4; grid-row: span 5; }
/* Stående ram: samma kolumner, fler rader (aspekt ~2:3). */
.gallery .sz-s.por { grid-row: span 5; }
.gallery .sz-m.por { grid-row: span 7; }
.gallery .sz-l.por { grid-row: span 9; }
.gallery a { display: block; width: 100%; height: 100%; }
.gallery img {
  width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; display: block;
}
/* Bildtextens tona är sajtens mörka BAS-färg genom taket för mörka ytor
   (--sea-deep-dark), som herons slöja: vit text i båda lägena. */
.gallery figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.1rem .7rem .45rem; font-size: .82rem; color: #fff;
  background: linear-gradient(transparent, color-mix(in srgb, var(--sea-deep-dark) 78%, transparent));
}
@media (max-width: 760px) {
  .gallery { grid-auto-rows: 64px; gap: .6rem; }
  .gallery .sz-s { grid-column: span 3; grid-row: span 3; }
  .gallery .sz-m { grid-column: span 6; grid-row: span 4; }
  .gallery .sz-l { grid-column: span 6; grid-row: span 5; }
  .gallery .sz-s.por { grid-row: span 4; }
  .gallery .sz-m.por { grid-column: span 3; grid-row: span 5; }
  .gallery .sz-l.por { grid-column: span 6; grid-row: span 8; }
  /* Ett stående och ett liggande foto, och inget mer: på datorn en hel
     rad (stående s bredvid liggande l), men på en telefon blev det
     stående en halv ruta med tomt bredvid och det liggande hamnade
     under. Två foton av olika form staplas därför i full bredd. Utan
     :has faller det tillbaka på reglerna ovan. */
  .gallery:has(> figure:nth-child(2):last-child):has(> .por):has(> figure:not(.por)) > figure {
    grid-column: span 6; grid-row: span 4;
  }
  .gallery:has(> figure:nth-child(2):last-child):has(> .por):has(> figure:not(.por)) > figure.por {
    grid-row: span 6;
  }
}
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, var(--sea-deep-base) 92%, transparent);
  display: flex; align-items: center; justify-content: center;
  cursor: zoom-out; padding: 2vh 2vw;
}
.lightbox img { max-width: 96vw; max-height: 96vh; border-radius: 6px; }

/* Kalender-embed */
.calendar-embed { position: relative; width: 100%; }
.calendar-embed iframe {
  width: 100%; height: 600px; border: 1px solid var(--rule); border-radius: 12px;
  background: var(--paper);
}

/* Kontakt + upplåsningsformulär */
/* Kontaktblocket låg tidigare i en egen max-width på SAMMA element som
   .wrap, som har margin:0 auto — resultatet blev en centrerad spalt
   medan varje annan sektion börjar vid vänsterkanten av 1100-spalten.
   Och .section.alt målade sin paper-bakgrund enbart på den smala rutan,
   så blocket läste som en lös låda mitt på sidan i stället för en del av
   sidan.
   Nu: full spaltbredd som resten, med texten till vänster och
   formuläret i en panel till höger. Panelen är det enda som avtecknar
   sig, och den gör det med avsikt. */
.contact-grid { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 54rem) {
  .contact-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 3.5rem; }
}
.contact-intro { max-width: 34rem; }
.contact-intro h2, .unlock h2 {
  color: var(--sea-deep-text);
  font-size: clamp(1.7rem, 3.4vw, 2.4rem);
  margin: 0 0 .7rem;
}
.contact-intro p { color: var(--ink-2); font-size: 1.05rem; margin: 0; }
/* Kontaktpersonen: runt porträtt med namn och roll under ingressen, så
   att den som skriver ser vem som svarar. Fotot är kundens eget, oftast
   stående och sällan centrerat på ansiktet; lite ovanför mitten träffar
   huvudet i ett vanligt porträtt bättre än mitten. Ringen är accentens
   färg, så porträttet hör till sajten och inte ser inklistrat ut. */
.contact-person {
  display: flex; align-items: center; gap: .85rem;
  margin: 1.8rem 0 0;
}
/* margin = ringens bredd, så att ringen linjerar med texten ovanför i
   stället för att sticka ut i marginalen. */
.contact-person img {
  flex: none; width: 5.5rem; height: 5.5rem; margin: 5px;
  border-radius: 50%; object-fit: cover; object-position: 50% 30%;
  background: var(--paper);
  box-shadow: 0 0 0 3px var(--sand), 0 0 0 5px color-mix(in srgb, var(--sea) 45%, transparent);
}
.contact-person figcaption { display: grid; gap: .15rem; line-height: 1.3; }
.contact-person strong { font-size: 1.1rem; color: var(--ink); }
.contact-person span { font-size: .95rem; color: var(--ink-2); }
.contact-person + .sent-ok { margin-top: 1.2rem; }
@media (min-width: 54rem) {
  .contact-person img { width: 6.5rem; height: 6.5rem; }
}

.contact-form, .unlock form {
  display: grid;
  gap: 1.1rem 1rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 16px;
  padding: clamp(1.4rem, 3vw, 2.1rem);
  box-shadow: var(--shadow);
}
/* Namn och e-post delar rad när panelen är bred nog. Container query:
   det är PANELENS bredd som avgör om två fält får plats, inte skärmens
   — panelen är halva spalten på desktop och hel på mobil. */
.contact-form { container-type: inline-size; }
@container (min-width: 26rem) {
  .contact-form { grid-template-columns: 1fr 1fr; }
  .contact-form .span-2, .contact-form button { grid-column: 1 / -1; }
}
.contact-form label, .unlock label { display: grid; gap: .45rem; }
.contact-form label > span, .unlock label {
  font-size: .78rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2);
}
.contact-form input, .contact-form textarea, .unlock input {
  font: inherit; color: var(--ink);
  padding: .8rem .9rem;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--sand);
  width: 100%;
  transition: border-color .15s, box-shadow .15s;
}
.contact-form textarea { resize: vertical; min-height: 8rem; }
.contact-form input::placeholder, .contact-form textarea::placeholder { color: var(--ink-2); opacity: .6; }
.contact-form input:focus, .contact-form textarea:focus, .unlock input:focus {
  outline: none;
  border-color: var(--sea);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--sea) 22%, transparent);
}
/* Samma tak som på .cta ovan, här för accenten (--sea-fill). Kunden
   väljer färgerna fritt i admin, och en ljus accent gav en skicka-knapp
   man inte kunde läsa. Hovern (--sea-deep-fill) gick förut rakt på
   --sea-deep, utan tak. */
.contact-form button, .unlock button {
  justify-self: start;
  padding: .85rem 1.9rem; border: 0; border-radius: 999px;
  background: var(--sea-fill); color: var(--paper); font: inherit; font-weight: 700;
  cursor: pointer; transition: background .15s, transform .1s;
}
.contact-form button:hover, .unlock button:hover { background: var(--sea-deep-fill); }
.contact-form button:active { transform: translateY(1px); }
/* Exempelsajtens formulär: fälten syns som på en riktig sajt men går
   inte att fylla i, och beskedet ovanför knappen säger varför. */
.contact-form :disabled { cursor: not-allowed; opacity: .6; }
.contact-form button:disabled:hover { background: var(--sea-fill); color: var(--paper); }
.contact-form button:disabled:active { transform: none; }
.demo-note { margin: 0; color: var(--ink-2); font-size: .95rem; }
.sent-ok { color: var(--sea-text); font-weight: 600; }
/* Felmeddelandet står på sanden. Tegelrött håller mot den i ljust läge
   (minst 4,8:1, också mot Ugnsluckans sand), men i mörkt läge gav det
   3,2:1 mot den mörka sanden. Där är det en ljusare ton av samma röda,
   6,2:1 mot sanden och 5,8:1 mot papperet. */
.unlock-error { color: #b3402a; font-weight: 600; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .unlock-error { color: #e8735c; }
}
:root[data-theme="dark"] .unlock-error { color: #e8735c; }

/* Footer */
footer { padding: 2.5rem 0; color: var(--ink-2); font-size: .88rem; border-top: 1px solid var(--rule); }
/* Plattformens rad under kundens egen: mindre, så att den aldrig tävlar
   med kundens namn. Färgen ärvs från texten runt omkring, så den följer
   temat och mörkt läge utan egna regler.

   Den var också dämpad, med 75 % opacitet, och det tog för mycket: den
   dämpade grå texten på sanden gav 3,3:1 i Norr med Ugnsluckans sand och
   4,5:1 i mörkt läge. Redan 90 % hade bara hållit med knapp marginal. Nu
   har den samma färg som raden ovanför, minst 5,6:1, och är dämpad bara
   genom storleken. */
footer .made-by { margin-top: .5rem; font-size: .8rem; }
footer .made-by a { color: inherit; }

/* Sociala kanaler: ikonrad i sidfoten och på kontaktsidan (sajtfronts
   social.html.tmpl). Allt utgår från currentColor, så raden följer
   texten runt omkring: temats färger, kundens färger, mörkt läge och
   medelhavs mörka sidfot, utan en regel per fall. Ytan är 2.5rem, stor
   nog för ett finger (WCAG 2.5.8 kräver 24px). */
.social {
  list-style: none; margin: 0 0 1rem; padding: 0;
  display: flex; flex-wrap: wrap; gap: .5rem;
}
.social a {
  display: inline-grid; place-items: center;
  width: 2.5rem; height: 2.5rem; border-radius: 999px;
  color: inherit;
  border: 1px solid;
  border-color: color-mix(in srgb, currentColor 35%, transparent);
  transition: background-color .15s, border-color .15s;
}
.social a:hover { border-color: currentColor; background: color-mix(in srgb, currentColor 12%, transparent); }
.social a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.social svg { width: 1.25rem; height: 1.25rem; display: block; }
/* På kontaktsidan står raden under ingressen, i accentfärgen. */
.contact-intro .social { margin: 1.5rem 0 0; color: var(--sea-text); }

/* Granskningsband – syns bara medan ett ogranskat AI-bygge ligger på
   sajten. Avsiktligt omöjligt att missa: den som landar här ska inte
   kunna tro att sajten är färdig. Försvinner när säljaren godkänt. */
.review-ribbon {
  background: #8a3b00;
  color: #fff;
  font-size: .8125rem;
  letter-spacing: .02em;
  text-align: center;
  padding: .5rem 1rem;
  position: sticky;
  top: 0;
  z-index: 50;
}
/* Exempelsajtens band: samma form (klassen review-ribbon sitter också på
   det), men lugnare och kvar överst i stället för att följa med ner. Det
   räcker att säga en gång att företaget är påhittat. Vit text på den
   mörka gröngrå tonen håller i både ljust och mörkt läge. */
.demo-ribbon { background: #2f3b33; position: static; }
.demo-ribbon a { margin-left: .35rem; text-decoration: underline; text-underline-offset: .15em; white-space: nowrap; }

/* Temaväxlare i sidhuvudet.
   Diskret: en ikon i samma vikt som språkväxlaren, inte en knapp som
   konkurrerar med sajtens egna. Ikonen visar vad man BYTER TILL — sol i
   mörkt läge, måne i ljust — vilket är den konvention folk känner igen. */
.theme-toggle {
  display: inline-grid; place-items: center;
  width: 2.25rem; height: 2.25rem; margin-left: .5rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: transparent; color: var(--ink-2);
  cursor: pointer; padding: 0;
  transition: color .15s, border-color .15s, background .15s;
}
.theme-toggle:hover { color: var(--sea-text); border-color: var(--sea); }
.theme-toggle:focus-visible {
  outline: none; border-color: var(--sea);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--sea) 25%, transparent);
}
.theme-toggle svg { grid-area: 1 / 1; }
/* Utan JS visas månen (sidan är ljus som default) — knappen gör inget då,
   men den ska inte se trasig ut. */
.theme-toggle .i-sun { display: none; }
.is-dark .theme-toggle .i-sun { display: block; }
.is-dark .theme-toggle .i-moon { display: none; }
