/* ============================================================
   SALONGSMALLEN — sektionsbibliotek
   ------------------------------------------------------------
   Layouten är densamma i alla tre teman. Det är HELA poängen:
   en kund byter tema, aldrig layout. Behöver en kund en sektion
   som inte finns här — bygg den här, med tokens, så att alla tre
   teman får den. Bygg den aldrig i en kundmapp.

   Klassnamnen är svenska för att matcha resten av repot.
   ============================================================ */

/* ---------- Behållare och band ------------------------------ */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--smal { max-width: 900px; }

/* Ett band = en sektion. Växlingen mellan .band, .band--alt och
   .band--mork är sidans rytm. Kör aldrig fler än tre ljusa band
   i rad utan ett mörkt avbrott. ART-DIRECTION.md §2. */
.band {
  padding-block: var(--section-y);
  background: var(--paper);
  color: var(--ink);
}
.band--alt   { background: var(--paper-alt); }
.band--tight { padding-block: var(--section-y-tight); }
.band--mork,
.pa-morkt {
  background: var(--surface);
  color: var(--surface-ink);
}
.band--mork p, .pa-morkt p { color: var(--surface-soft); }
.band--mork .eyebrow, .pa-morkt .eyebrow { color: var(--accent-on-dark); }

/* ---------- Typografiska komponenter ------------------------ */

/* Versaletikett. Spärrningen ÄR effekten — sänk den inte. */
.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1.1rem;
}

/* Skrivstilsögonbryn — salongssignaturen. Aldrig hela meningar. */
.script {
  display: block;
  font-family: var(--font-script);
  font-size: var(--t-script);
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  color: var(--accent);
  margin: 0 0 0.5rem;
}
.pa-morkt .script, .band--mork .script { color: var(--accent-on-dark); }

.display { font-size: var(--t-display); }
.h2      { font-size: var(--t-h2); }
.h3 {
  font-size: var(--t-h3);
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
}

.lede {
  font-size: calc(var(--t-body) * 1.1);
  color: var(--ink-soft);
  margin-top: 1.5rem;
}
.pa-morkt .lede, .band--mork .lede { color: var(--surface-soft); }

/* Överdimensionerad skrivstil bakom innehåll. Låg opacitet,
   aldrig läsbar-viktig text. */
.stampel {
  font-family: var(--font-script);
  font-size: clamp(4rem, 15vw, 12rem);
  line-height: 0.8;
  color: var(--accent);
  opacity: 0.12;
  text-transform: none;
  letter-spacing: 0;
  pointer-events: none;
  user-select: none;
}

/* ---------- Knappar ----------------------------------------- */

.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1.15em 2.4em;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
.btn:hover { background: transparent; color: var(--accent); }

.btn--kontur {
  background: transparent;
  color: var(--accent);
  border-color: var(--accent);
}
.btn--kontur:hover { background: var(--accent); color: var(--accent-ink); }

.pa-morkt .btn, .band--mork .btn {
  background: var(--accent-on-dark);
  border-color: var(--accent-on-dark);
  color: var(--surface);
}
.pa-morkt .btn:hover, .band--mork .btn:hover {
  background: transparent;
  color: var(--accent-on-dark);
}
.pa-morkt .btn--kontur, .band--mork .btn--kontur {
  background: transparent;
  color: var(--surface-ink);
  border-color: var(--line-on-dark);
}
.pa-morkt .btn--kontur:hover, .band--mork .btn--kontur:hover {
  border-color: var(--accent-on-dark);
  color: var(--accent-on-dark);
}

/* ---------- Hero -------------------------------------------- */

.hero {
  position: relative;
  /* Höjd från 780 till 880. Vid 780 blev heron märkbart kortare än
     förlagornas och kändes trång — syntes först i sida-vid-sida.
     min() gör att ett högt skärmdumpsfönster inte förvränger den. */
  min-height: min(88vh, 880px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--surface);
}
.hero__bild {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Långsam zoom. Enda rörelsen i hero. */
  animation: heroZoom 22s var(--ease) forwards;
}
@keyframes heroZoom { from { transform: scale(1.06); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  .hero__bild { animation: none; }
}
/* Skuggan är en gradient, inte en platt overlay — platt overlay
   gör fotot grått, gradienten låter det behålla djupet. */
.hero__skugga {
  position: absolute; inset: 0;
  background: linear-gradient(
    to top,
    rgba(0,0,0,.72) 0%,
    rgba(0,0,0,.42) 38%,
    rgba(0,0,0,.10) 70%,
    rgba(0,0,0,.28) 100%);
}
.hero__innehall {
  position: relative;
  width: 100%;
  padding-block: clamp(3rem, 7vw, 6rem);
  color: #fff;
  /* Bred och mjuk — syns inte som skugga, men lyfter texten från
     ett foto vars ljushet vi inte kan förutse. */
  text-shadow: 0 1px 28px rgba(0, 0, 0, 0.45);
}
.hero__innehall .display { color: #fff; }

/* Hero ligger på FOTO, inte på --paper. Accenten som är avstämd
   mot cream blir nästan oläslig här — särskilt nordisk-ljus salvia
   mot ett ljust foto. Hela hero använder därför den ljusa
   varianten, samma som mörka band gör. */
/* --accent-foto, inte --accent-on-dark. Den senare följer läget och
   pekar i ljust läge på den MÖRKA accenttonen — vilket gav svart
   ögonbryn på ett mörkt foto i monokromt mörkt läge. Ett foto är
   alltid en mörk yta oavsett vilket läge sidan är i. Se tokens.css. */
.hero__innehall .script,
.hero__innehall .eyebrow { color: var(--accent-foto); }
.hero .hero__innehall :where(h1, h2, h3, .display, .h2) em { color: var(--accent-foto); }

.hero .btn {
  background: var(--accent-foto);
  border-color: var(--accent-foto);
  color: var(--surface);
  text-shadow: none;
}
.hero .btn:hover { background: transparent; color: var(--accent-foto); }
.hero .btn--kontur {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.55);
}
.hero .btn--kontur:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: #fff;
  color: #fff;
}

.hero__knappar { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 2.5rem; }

/* ============================================================
   PRIORITET 1 UR BYGGLISTAN
   Grepp som saknades och som förklarar mest av kvalitetsgapet
   mot förlagorna. Se referenser/BYGGLISTA.md.
   ============================================================ */

/* ---------- Ghost-typ i hero -------------------------------- */

/* En mega-rubrik i mycket låg kontrast som ligger delvis bakom
   fotot. Sett i tre av sex haires-demos, placerad vänster,
   centrerad eller längs underkanten.

   Det som gör den svår att härma är att den ska vara STOR och
   NÄSTAN OSYNLIG samtidigt. Går man för högt i opacitet blir det
   bara en ljusgrå rubrik; för lågt och den försvinner. 0.18–0.26
   mot ett foto är intervallet som fungerar.

   Rubriken är dekor, inte information — därför ligger den riktiga
   rubriken kvar i .hero__innehall. Skärmläsare ska inte läsa
   samma mening två gånger. */
.ghosttyp {
  position: absolute;
  inset-inline: 0;
  z-index: 1;
  margin: 0;
  padding-inline: var(--gutter);
  font-family: var(--font-display);
  /* Nedskalad från 11rem. Vid full storlek kolliderade den med den
     riktiga rubriken och båda blev oläsliga — syntes först i
     sida-vid-sida-jämförelsen. Ghost-typen ska ANAS, inte läsas. */
  font-size: clamp(2.5rem, 7.5vw, 7rem);
  line-height: 0.95;
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-transform: var(--display-case);
  color: #fff;
  opacity: 0.13;
  pointer-events: none;
  user-select: none;
}
/* Den riktiga rubriken ligger nere till vänster. Ghost-typen
   placeras därför i motsatt hörn i alla varianter — de får aldrig
   dela yta. */
.ghosttyp--mitt   { top: 14%; text-align: center; }
.ghosttyp--botten { bottom: clamp(1rem, 3vw, 3rem); text-align: right; }
.ghosttyp--vanster{ top: 12%; }

/* ---------- Konturtyp --------------------------------------- */

/* Hålrubrik i outline. Cassini 04 kör den i full sidbredd över
   ett foto — det starkaste typografiska greppet i hela
   referensmaterialet.

   text-stroke saknar stöd i äldre Firefox; där faller den tillbaka
   på fylld text, vilket är fult men läsbart. Därför aldrig till
   sidans enda rubrik. */
/* Frågan ställs POSITIVT med flit. `@supports not (-webkit-text-stroke: …)`
   returnerar sant i Edge trots att egenskapen fungerar — feature-frågor
   validerar inte prefixade egenskaper pålitligt. Med negationen slog
   reservläget till överallt och rubriken blev fylld grå i stället för
   ihålig. Grundläget är därför vanlig text, och konturen läggs på först
   när stödet är bevisat. */
/* Konturtyp kräver TUNG vikt. I ett tema med rubrikvikt 300 blir
   bokstavsstammen knappt tjockare än konturen och greppet läser
   som suddig fylld text. Verifierat i rendering — det såg
   tekniskt rätt ut och visuellt fel.
   Vikten sätts därför här och ärvs inte från temat. */
.display--kontur {
  color: inherit;
  font-weight: 800;
  letter-spacing: -0.015em;
  font-size: clamp(3rem, 11vw, 9rem);
  line-height: 0.95;
}
@supports (-webkit-text-stroke-color: red) {
  .display--kontur {
    color: transparent;
    -webkit-text-stroke-width: 1.5px;
    /* Explicit färg, ALDRIG currentColor: color:transparent gör att
       currentColor också blir genomskinlig och konturen försvinner
       spårlöst. Det tog två renderingar att hitta. */
    -webkit-text-stroke-color: var(--ink);
  }
  .pa-morkt .display--kontur,
  .band--mork .display--kontur { -webkit-text-stroke-color: var(--surface-ink); }
  /* Måste vara .hero__innehall, inte .hero. Rubriken i heron träffas
     av `.hero__innehall .display { color: #fff }` med specificitet
     (0,2,0); `.display--kontur` ligger på (0,1,0) och förlorar. Då
     blir konturtypen SOLIDT vit — den ser ut som en vanlig rubrik och
     hela greppet försvinner utan att något ser trasigt ut.
     Tredje gången det här greppet gick sönder på ett nytt sätt. */
  .hero__innehall .display--kontur {
    color: transparent;
    -webkit-text-stroke-color: #fff;
  }
}

/* ---------- Bakgrundsgrafik i jätteformat ------------------- */

/* Urblekt grafik bakom en hel sektion — sax, kam, sköld. Sett
   bakom prislistan (haires 01) och om-sektionen (haires 02) och
   som hårfina konturer vid sidkanterna (haires 03).

   Fyller tomrum utan att lägga till innehåll att läsa. Det är
   skillnaden mot en tom sektion som bara ser oavslutad ut. */
.band { position: relative; }
.bakgrundsgrafik {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.bakgrundsgrafik svg {
  width: clamp(320px, 46vw, 720px);
  height: auto;
  color: var(--ink);
  opacity: 0.045;
}
.pa-morkt .bakgrundsgrafik svg,
.band--mork .bakgrundsgrafik svg { color: var(--surface-ink); opacity: 0.06; }

/* Kantvarianten: två hårfina konturer vid sidkanterna i stället
   för en fylld i mitten. */
.bakgrundsgrafik--kanter { place-items: center space-between; }
.bakgrundsgrafik--kanter svg {
  width: clamp(180px, 18vw, 320px);
  opacity: 0.07;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
}
.band > .wrap { position: relative; z-index: 1; }

/* ---------- Roterande text-på-cirkel ------------------------ */

/* Stort märke med text längs en cirkelbana runt en rund bild.
   Återkommer i fem av sex haires-demos — sidans mest utmärkande
   enskilda element.

   Texten sätts som SVG textPath i markupen; här ligger bara
   rotationen och skalan. */
.cirkelmarke {
  position: relative;
  width: clamp(180px, 26vw, 340px);
  aspect-ratio: 1;
  margin-inline: auto;
  display: grid;
  place-items: center;
}
.cirkelmarke__ring {
  position: absolute;
  inset: 0;
  animation: snurra 26s linear infinite;
}
.cirkelmarke__ring text {
  font-family: var(--font-body);
  font-size: 8.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  fill: var(--ink);
}
.pa-morkt .cirkelmarke__ring text,
.band--mork .cirkelmarke__ring text { fill: var(--surface-ink); }
.cirkelmarke__bild {
  width: 58%;
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  object-fit: cover;
}
@keyframes snurra { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cirkelmarke__ring { animation: none; }
}

/* ---------- Riven sektionskant ------------------------------ */

/* Penseldragen övergång mellan hero och nästa sektion i stället
   för en rak linje. Sett i haires 01 och 02.

   Görs med clip-path så att inget extra element behövs och
   ingenting behöver laddas. Formen är medvetet oregelbunden —
   en symmetrisk våg ser ut som en mall från 2018. */
.riven-kant {
  clip-path: polygon(
    0 0, 100% 0, 100% 96%,
    92% 99%, 84% 96.5%, 76% 99.5%, 68% 97%, 61% 99%,
    52% 96%, 44% 99%, 36% 97%, 27% 99.5%, 19% 97%, 11% 99%, 4% 97.5%, 0 99%
  );
}

/* ---------- Bokningsrad i heron ----------------------------- */

/* Cassini 01 lägger datum, tid och knapp som en rad direkt under
   hero-rubriken. Det starkaste konverteringsgreppet i hela
   referensmaterialet — bokningen börjar innan besökaren scrollat.

   Fälten är understrukna, inte inramade, precis som .falt. */
.bokningsrad {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  align-items: end;
  gap: clamp(1rem, 2vw, 2rem);
  margin-top: 2.5rem;
  padding: clamp(1.25rem, 2vw, 1.75rem) clamp(1.25rem, 2.5vw, 2rem);
  /* Solid grund, oskärpa som förbättring ovanpå. backdrop-filter
     komponeras inte alltid — panelen blev nästan osynlig i
     renderingen och fälten såg ut att saknas helt. */
  background: rgba(12, 10, 9, 0.72);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  max-width: 820px;
}
.bokningsrad .falt label { color: rgba(255, 255, 255, 0.72); }
.bokningsrad .falt input,
.bokningsrad .falt select {
  color: #fff;
  /* Fälten måste synas som fält. En knappt skönjbar underkant på
     mörk panel läser som tom yta, inte som något ifyllbart. */
  border-bottom: 1px solid rgba(255, 255, 255, 0.5);
  min-height: 2.6rem;
}
.bokningsrad .falt input:focus,
.bokningsrad .falt select:focus { border-bottom-color: var(--accent-on-dark); }
.bokningsrad .falt select option { color: var(--ink); background: var(--paper); }
.bokningsrad .btn { align-self: end; }
@media (max-width: 640px) {
  .bokningsrad { background: rgba(0,0,0,.55); }
}

/* ============================================================
   PRIORITET 2 UR BYGGLISTAN
   ============================================================ */

/* ---------- Pillerlist över heron --------------------------- */

/* En ljus, helrundad list som överlappar hero-underkanten, med sex
   ikontjänster i rad. Från haires 05.

   Skillnaden mot .herokort: korten är bilder, listen är en enda
   ljus yta. Den fungerar när salongen INTE har fyra bra bilder —
   och det är vanligare än motsatsen. Använd aldrig båda. */
.pillerlist {
  position: relative;
  z-index: 2;
  margin-top: clamp(-4.5rem, -6vw, -3rem);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  background: var(--surface);
  color: var(--surface-ink);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.pillerlist__post {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  padding: clamp(1.5rem, 2.6vw, 2.25rem) 1rem;
  text-align: center;
  text-decoration: none;
  color: inherit;
  border-right: 1px solid var(--line-on-dark);
  transition: background var(--t-fast) var(--ease);
}
.pillerlist__post:last-child { border-right: 0; }
.pillerlist__post:hover { background: color-mix(in srgb, var(--surface-ink) 7%, transparent); }
.pillerlist__post svg { width: 30px; height: 30px; stroke-width: 1.2; color: var(--accent-on-dark); }
.pillerlist__namn {
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
/* Piller på en tvåradig list ser ut som ett misstag — vid ombrytning
   blir hörnen räta i stället. */
@media (max-width: 900px) {
  .pillerlist { border-radius: 0; margin-top: clamp(-2.5rem, -4vw, -1.5rem); }
  .pillerlist__post { border-bottom: 1px solid var(--line-on-dark); }
}

/* ---------- Tvåspaltig prislista ---------------------------- */

/* Från haires 01: två spalter, beskrivning under VARJE rad, och en
   urblekt bakgrundsgrafik bakom hela sektionen.

   Halverar sidhöjden på en lång prislista. Under 900px faller den
   till en spalt — två smala priskolumner är oläsligt på mobil. */
.pris--tva {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(2.5rem, 6vw, 5.5rem);
  row-gap: 1.4rem;
}
@media (max-width: 900px) { .pris--tva { grid-template-columns: 1fr; } }

/* Valutan upphöjd och mindre — priset läser som en siffra, inte
   som en text. */
.pris__belopp sup {
  font-size: 0.62em;
  vertical-align: 0.5em;
  margin-right: 0.1em;
  font-weight: 400;
}

/* ---------- Förskjutet galleri ------------------------------ */

/* Bilderna ligger på olika höjd i stället för i linje. Från
   haires 01. Ett rutnät där allt börjar på samma rad läser som en
   tabell; förskjutningen läser som en komposition.

   Etikett under varje bild, inte i den. */
.forskjutet {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(1rem, 2vw, 1.75rem);
  align-items: start;
}
.forskjutet__post:nth-child(2n)   { margin-top: clamp(1.5rem, 4vw, 3.5rem); }
.forskjutet__post:nth-child(3n+1) { margin-top: clamp(0.75rem, 2vw, 1.75rem); }
.forskjutet__post img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.forskjutet__etikett {
  display: block;
  margin-top: 0.9rem;
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.pa-morkt .forskjutet__etikett, .band--mork .forskjutet__etikett { color: var(--surface-soft); }
@media (max-width: 640px) {
  .forskjutet__post { margin-top: 0 !important; }
}

/* ---------- Stadionformad videoruta ------------------------- */

/* Nästan full bredd, extremt stor radie i båda ändar, cirkulär
   konturspelaknapp i mitten. Från haires 01.

   Det här är radie-regeln i praktiken: 0 eller extremt, aldrig
   8–12px. Se ART-DIRECTION §1. */
.stadionvideo {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 21 / 9;
  overflow: hidden;
  border-radius: clamp(120px, 22vw, 320px);
  text-decoration: none;
  color: #fff;
}
.stadionvideo img { width: 100%; height: 100%; object-fit: cover; }
.stadionvideo::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.28);
  transition: background var(--t-slow) var(--ease);
}
.stadionvideo:hover::after { background: rgba(0, 0, 0, 0.4); }
.stadionvideo__spela {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-content: center; justify-items: center;
  gap: 1rem;
  text-shadow: 0 1px 16px rgba(0,0,0,.5);
}
.stadionvideo__knapp {
  width: clamp(64px, 8vw, 96px);
  aspect-ratio: 1;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: var(--radius-pill);
  display: grid; place-items: center;
  transition: background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.stadionvideo:hover .stadionvideo__knapp { background: rgba(255,255,255,.16); transform: scale(1.06); }
.stadionvideo__etikett {
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
}
@media (max-width: 640px) {
  .stadionvideo { aspect-ratio: 4 / 3; border-radius: clamp(48px, 16vw, 90px); }
}

/* ---------- Hero-varianter ---------------------------------- */

/* Hero är det första besökaren ser. Två sajter med olika hero
   läser som olika sajter även med samma tema — och det är därför
   varianterna finns. Se RECEPT.md.

   Grundklassen .hero är helbildsvarianten. Nedan ligger de tre
   andra som modifierare. */

/* Delad: foto på ena halvan, text på den andra. Lugnare än
   helbild och den enda varianten där texten aldrig ligger på
   ett foto — bra när salongens bilder är stökiga. */
.hero--delad {
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  background: var(--paper);
}
.hero--delad .hero__bild {
  position: relative;
  height: 100%;
  min-height: clamp(320px, 46vw, 620px);
  animation: none;
}
.hero--delad .hero__skugga { display: none; }
.hero--delad .hero__innehall {
  color: var(--ink);
  text-shadow: none;
  display: flex;
  align-items: center;
  padding: clamp(2.5rem, 5vw, 5rem) 0;
}
.hero--delad .hero__innehall .display { color: var(--ink); }
.hero--delad .hero__innehall .script,
.hero--delad .hero__innehall .eyebrow { color: var(--accent); }
.hero--delad .hero__innehall :where(h1, h2, .display, .h2) em { color: var(--accent); }
.hero--delad .btn {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}
.hero--delad .btn:hover { background: transparent; color: var(--accent); }
.hero--delad .btn--kontur {
  background: transparent; color: var(--accent); border-color: var(--accent);
}
.hero--delad .btn--kontur:hover { background: var(--accent); color: var(--accent-ink); }
.hero--delad .wrap { max-width: 640px; margin-inline: 0; padding-inline: var(--gutter); }
@media (max-width: 820px) {
  .hero--delad { grid-template-columns: 1fr; }
  .hero--delad .hero__bild { min-height: 300px; }
}

/* Centrerad: lägre hero, texten mitt i. Mest neutral av alla —
   fungerar när fotot är starkt nog att bära ensamt. */
.hero--centrerad {
  min-height: min(64vh, 600px);
  align-items: center;
  text-align: center;
}
.hero--centrerad .hero__knappar { justify-content: center; }
.hero--centrerad .wrap { max-width: 780px; }

/* Typografisk: rubriken dominerar, bilden är underordnad.
   Greppet kommer från Cassini 02 — se referenser/cassini-layouter.md.
   Kräver en riktigt bra rubrik; utan den blir sidan bara tom. */
.hero--typografisk {
  min-height: 0;
  background: var(--paper);
  display: block;
}
.hero--typografisk .hero__bild {
  position: relative;
  height: clamp(220px, 30vw, 420px);
  margin-top: clamp(2rem, 4vw, 3.5rem);
  animation: none;
}
.hero--typografisk .hero__skugga { display: none; }
.hero--typografisk .hero__innehall {
  color: var(--ink);
  text-shadow: none;
  padding-block: clamp(3.5rem, 8vw, 7rem) 0;
}
.hero--typografisk .hero__innehall .display {
  color: var(--ink);
  font-size: clamp(2.75rem, 9vw, 7.5rem);   /* medvetet större än basen */
}
.hero--typografisk .hero__innehall .script,
.hero--typografisk .hero__innehall .eyebrow { color: var(--accent); }
.hero--typografisk .hero__innehall :where(h1, h2, .display, .h2) em { color: var(--accent); }
.hero--typografisk .btn {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
}
.hero--typografisk .btn:hover { background: transparent; color: var(--accent); }
.hero--typografisk .btn--kontur {
  background: transparent; color: var(--accent); border-color: var(--accent);
}
.hero--typografisk .btn--kontur:hover { background: var(--accent); color: var(--accent-ink); }

/* Herokorten hänger ihop med helbilds-heron. Ligger hero:n inte
   på ett foto finns inget att dra upp över — nollställ då
   marginalen, annars äter korten upp texten ovanför. */
.hero--delad + .band .herokort,
.hero--typografisk + .band .herokort { margin-top: 0; }
.hero--delad + .band,
.hero--typografisk + .band { padding-top: var(--section-y-tight); }

/* ---------- Numrerade steg --------------------------------- */

/* Från Cassini 03. Siffran är det grafiska elementet — stor,
   tunn, i accentfärg. Tre steg, aldrig fler: "så här går det
   till" tappar sin poäng vid fyra. */
.steg {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem);
  counter-reset: steg;
}
.steg__post { counter-increment: steg; }
.steg__post::before {
  content: counter(steg, decimal-leading-zero);
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 4.5vw, 3.75rem);
  line-height: 1;
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  color: var(--accent);
  margin-bottom: 1.1rem;
}
.pa-morkt .steg__post::before, .band--mork .steg__post::before { color: var(--accent-on-dark); }
.steg__titel {
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 0.7rem;
}
.steg p { font-size: var(--t-small); color: var(--ink-soft); }
.pa-morkt .steg p, .band--mork .steg p { color: var(--surface-soft); }

/* ---------- Prisnivåer -------------------------------------- */

/* Alternativ till .pris för salonger som prissätter per frisörs
   nivå i stället för per behandling. Från Cassini 03.
   Använd ANTINGEN .pris ELLER .prisnivaer — aldrig båda. */
.prisnivaer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}
.prisniva {
  padding: clamp(2rem, 3.4vw, 3rem);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.prisniva__namn {
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--accent);
}
.pa-morkt .prisniva__namn, .band--mork .prisniva__namn { color: var(--accent-on-dark); }
.prisniva__belopp {
  font-family: var(--font-display);
  font-size: clamp(2rem, 3.4vw, 2.75rem);
  line-height: 1;
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-transform: var(--display-case);
}
.prisniva__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.prisniva__lista li {
  font-size: var(--t-small);
  color: var(--ink-soft);
  padding-left: 1.1rem;
  position: relative;
}
.prisniva__lista li::before {
  content: '—';
  position: absolute; left: 0;
  color: var(--accent);
}
.pa-morkt .prisniva__lista li, .band--mork .prisniva__lista li { color: var(--surface-soft); }
.prisniva .btn { margin-top: auto; align-self: start; }

/* ---------- Kort som överlappar heron ----------------------- */

/* Fyra kategorikort som dras upp över hero-fotots underkant. Det
   här greppet gör mer för "tät och designad" än något annat i
   biblioteket: sidan börjar inte om efter heron, den fortsätter.

   Läggs i ett eget .band DIREKT efter .hero. Det negativa
   toppmarginalet är avsiktligt kopplat till kortens höjd —
   ändrar du det ena, kontrollera det andra. */
.herokort {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(0.5rem, 1vw, 1rem);
  margin-top: clamp(-11rem, -13vw, -7rem);
  position: relative;
  z-index: 2;
}
.herokort__kort {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  text-decoration: none;
  color: #fff;
}
.herokort__kort img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.herokort__kort:hover img { transform: scale(1.05); }
.herokort__kort::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.78) 0%, rgba(0,0,0,.18) 52%, transparent 100%);
}
.herokort__text {
  position: absolute; inset-inline: 0; bottom: 0;
  z-index: 1;
  padding: clamp(1rem, 1.6vw, 1.5rem);
  text-shadow: 0 1px 16px rgba(0,0,0,.5);
}
.herokort__etikett {
  display: block;
  font-family: var(--font-script);
  font-size: 1.35rem;
  line-height: 1;
  color: var(--accent-on-dark);
  margin-bottom: 0.35rem;
}
.herokort__namn {
  display: block;
  font-family: var(--font-body);
  font-size: var(--t-label);
  font-weight: 500;
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
}
@media (max-width: 780px) {
  .herokort { grid-template-columns: repeat(2, 1fr); margin-top: clamp(-5rem, -9vw, -3rem); }
}

/* ---------- Tjänstgalleri: bild med etikett i bilden -------- */

/* Skillnaden mot .mosaik: mosaiken är bevis utan text, det här är
   navigering. Använd inte båda på samma sida — då blir det två
   bildväggar som konkurrerar. */
.tjanstgalleri {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(0.5rem, 1vw, 1rem);
}
.tjanstkort {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  text-decoration: none;
  color: #fff;
}
.tjanstkort img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow) var(--ease);
}
.tjanstkort:hover img { transform: scale(1.04); }
.tjanstkort::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.12) 58%, transparent 100%);
  transition: background var(--t-slow) var(--ease);
}
.tjanstkort:hover::after {
  background: linear-gradient(to top, rgba(0,0,0,.82) 0%, rgba(0,0,0,.3) 65%, rgba(0,0,0,.1) 100%);
}
.tjanstkort__text {
  position: absolute; inset-inline: 0; bottom: 0; z-index: 1;
  padding: clamp(1.1rem, 2vw, 1.75rem);
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  text-shadow: 0 1px 16px rgba(0,0,0,.5);
}
.tjanstkort__namn {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-transform: var(--display-case);
  line-height: 1.15;
}
.tjanstkort__pris {
  font-family: var(--font-body);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-on-dark);
  white-space: nowrap;
}

/* ---------- Triptyk (tre tjänster) -------------------------- */

.triptyk {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}
.triptyk__kort {
  padding: clamp(2rem, 3.4vw, 3.25rem);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  transition: background var(--t-slow) var(--ease);
}
.triptyk__kort:hover { background: var(--paper-alt); }
.triptyk__kort .h3 { margin-bottom: 0.75rem; }
.triptyk__kort p { font-size: var(--t-small); color: var(--ink-soft); }

/* ---------- Prislista med prickad ledarlinje ---------------- */

.pris { display: grid; gap: 1.4rem; }
.pris__rad {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.75rem;
}
.pris__namn { font-family: var(--font-body); font-weight: 500; }
/* Ledarlinjen ska synas. --line är avstämd för sektionsramar och
   blir för svag här — prickarna är det som gör att raden läses
   som en prislista och inte som två lösa ord. */
.pris__prickar {
  border-bottom: 1px dotted color-mix(in srgb, var(--ink) 34%, transparent);
  transform: translateY(-0.28em);
}
.pa-morkt .pris__prickar, .band--mork .pris__prickar {
  border-bottom-color: color-mix(in srgb, var(--surface-ink) 34%, transparent);
}
.pris__belopp {
  font-family: var(--font-body);
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pa-morkt .pris__belopp, .band--mork .pris__belopp { color: var(--accent-on-dark); }
.pris__beskrivning {
  grid-column: 1 / -1;
  margin-top: -0.9rem;
  font-size: var(--t-small);
  color: var(--ink-soft);
}
.pa-morkt .pris__beskrivning, .band--mork .pris__beskrivning { color: var(--surface-soft); }

/* ---------- Mosaik: OLIKA stora celler, aldrig ett rutnät --- */

.mosaik {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: clamp(110px, 13vw, 190px);
  gap: clamp(0.5rem, 1vw, 1rem);
}
.mosaik img { width: 100%; height: 100%; object-fit: cover; }
.mosaik > :nth-child(1) { grid-column: span 2; grid-row: span 2; }
.mosaik > :nth-child(2) { grid-column: span 2; grid-row: span 1; }
.mosaik > :nth-child(3) { grid-column: span 1; grid-row: span 1; }
.mosaik > :nth-child(4) { grid-column: span 1; grid-row: span 1; }
@media (max-width: 640px) {
  .mosaik { grid-template-columns: repeat(2, 1fr); }
  .mosaik > :nth-child(1) { grid-column: span 2; grid-row: span 2; }
  .mosaik > :nth-child(2) { grid-column: span 2; }
}

/* ---------- Statistikrad ------------------------------------ */

.statistik {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}
.statistik__post { border-left: 1px solid var(--line-on-dark); padding-left: 1.5rem; }
.statistik__tal {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 4vw, 3.5rem);
  line-height: 1;
  letter-spacing: var(--display-tracking);
  color: var(--accent-on-dark);
}
.statistik__etikett {
  display: block;
  margin-top: 0.85rem;
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--surface-soft);
}

/* ---------- Två spalter: text + bild ------------------------ */

.duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}

/* Cirkelstämpeln som överlappar ett foto — "16 år i branschen".
   Ett litet påstående med stor siffra, aldrig en logotyp. */
.duo__bild { position: relative; }
.cirkelstampel {
  position: absolute;
  top: 8%; right: -1.75rem;
  width: clamp(96px, 11vw, 132px);
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-ink);
  display: grid;
  place-content: center;
  text-align: center;
  padding: 0.5rem;
}
.cirkelstampel b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.4vw, 2.2rem);
  line-height: 1;
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
}
.cirkelstampel span {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--font-body);
  font-size: 9px;
  line-height: 1.35;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* ---------- Sidhuvud ---------------------------------------- */

/* Nyttorad överst: öppettider, ort, telefon. Liten, spärrad,
   aldrig navigering. Försvinner under 900px. */
.topbar {
  background: var(--paper-alt);
  border-bottom: 1px solid var(--line);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.topbar__rad {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.85rem;
}
.topbar a { text-decoration: none; }
.topbar a:hover { color: var(--accent); }
@media (max-width: 900px) { .topbar { display: none; } }

/* Huvudet: navigering vänster, logotyp CENTRERAD, telefon + knapp
   höger. Den centrerade logotypen är salongskonventionen — ett
   vänsterställt märke läser som byrå eller butik. */
.sidhuvud {
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.sidhuvud__rad {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.5rem;
  padding-block: 1.1rem;
}
.sidhuvud__nav { display: flex; gap: clamp(1rem, 2.2vw, 2.25rem); }
.sidhuvud__nav a {
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  padding-block: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.sidhuvud__nav a:hover,
.sidhuvud__nav a[aria-current="page"] { color: var(--accent); border-bottom-color: var(--accent); }

.sidhuvud__logo {
  justify-self: center;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.6vw, 1.35rem);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  text-decoration: none;
  line-height: 1;
}
.sidhuvud__hoger { display: flex; align-items: center; gap: 1.25rem; justify-self: end; }
.sidhuvud__tel {
  font-size: var(--t-small);
  letter-spacing: 0.08em;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.sidhuvud__tel:hover { color: var(--accent); }

.burgare {
  display: none;
  background: none; border: 0; padding: 0.5rem;
  color: inherit; cursor: pointer;
}
@media (max-width: 900px) {
  .sidhuvud__rad { grid-template-columns: auto 1fr auto; }
  .sidhuvud__nav { display: none; }
  .sidhuvud__nav[data-oppen="true"] {
    display: flex; flex-direction: column; gap: 0;
    grid-column: 1 / -1; padding-block: 1rem;
    border-top: 1px solid var(--line);
  }
  .sidhuvud__nav[data-oppen="true"] a { padding-block: 0.85rem; border-bottom: 0; }
  .sidhuvud__logo { justify-self: start; }
  .sidhuvud__tel { display: none; }
  .burgare { display: block; }
}

/* ---------- Sidhero för undersidor -------------------------- */

/* Undersidor får inte samma stora hero som startsidan. De får ett
   lågt mörkt band: centrerad versalrubrik + brödsmula. Skillnaden
   i höjd är det som säger "det här är inte förstasidan". */
.sidhero {
  position: relative;
  min-height: clamp(220px, 30vw, 340px);
  display: grid;
  place-items: center;
  text-align: center;
  background: var(--surface);
  color: var(--surface-ink);
  overflow: hidden;
}
.sidhero__bild {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.5;
}
.sidhero__innehall { position: relative; padding-block: clamp(2.5rem, 5vw, 4rem); }
.sidhero .display, .sidhero .h2 { color: #fff; }
.brodsmula {
  margin-top: 1.1rem;
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--surface-soft);
}
.brodsmula a { text-decoration: none; }
.brodsmula a:hover { color: var(--accent-on-dark); }

/* ---------- Flikar (prislista per frisörnivå) --------------- */

.flikar {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-bottom: clamp(2rem, 3.5vw, 3rem);
}
.flik {
  font-family: var(--font-body);
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.95em 1.9em;
  background: transparent;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.flik:hover { color: var(--ink); border-color: var(--ink); }
.flik[aria-selected="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* ---------- Dragspel (vanliga frågor) ----------------------- */

.dragspel { border-top: 1px solid var(--line); }
.dragspel__post { border-bottom: 1px solid var(--line); }
.dragspel__knapp {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: 1.5rem 0;
  background: none; border: 0;
  font-family: var(--font-body);
  font-size: var(--t-body);
  font-weight: 500;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.dragspel__knapp:hover { color: var(--accent); }
/* Ingen ram runt ikonen. Rotationen 45° gäller hela elementet —
   med ram blir plustecknet en romb istället för ett kryss. */
.dragspel__ikon {
  flex: none;
  width: 1.5rem; height: 1.5rem;
  display: grid; place-items: center;
  font-size: 1.35rem;
  line-height: 1;
  color: var(--accent);
  transition: transform var(--t-slow) var(--ease);
}
.dragspel__knapp[aria-expanded="true"] .dragspel__ikon { transform: rotate(45deg); }
.dragspel__svar { padding-bottom: 1.6rem; color: var(--ink-soft); font-size: var(--t-small); }
.dragspel__svar[hidden] { display: none; }

/* ---------- Team -------------------------------------------- */

/* Riktiga människor säljer salonger. Porträtten ska vara tagna i
   lokalen, inte i studio — och alla i samma ljus. */
.team {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
}
.team__kort { display: grid; gap: 1rem; }
.team__bild { aspect-ratio: 3 / 4; width: 100%; object-fit: cover; }
/* Namn är information, inte display. En hårfin displayserif på
   23px blir gråtunn och svårläst — och ett personnamn är det
   sista på sidan man vill kisa efter. */
.team__namn {
  font-family: var(--font-body);
  font-size: var(--t-h3);
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.2;
}
.team__roll {
  margin-top: 0.4rem;
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--accent);
}

/* ---------- Omdömen ----------------------------------------- */

.omdomen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(1rem, 2vw, 1.75rem);
}
.omdome {
  position: relative;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--paper);
  border: 1px solid var(--line);
}
.band--alt .omdome { background: var(--paper-alt); }
.omdome__citat {
  position: absolute; top: 1rem; right: 1.5rem;
  font-family: var(--font-display);
  font-size: 3.5rem; line-height: 1;
  color: var(--accent); opacity: 0.2;
  pointer-events: none;
}
.omdome p { font-size: var(--t-small); color: var(--ink-soft); }
.omdome__vem { display: flex; align-items: center; gap: 0.85rem; margin-bottom: 1.1rem; }
.omdome__vem img { width: 44px; height: 44px; object-fit: cover; border-radius: var(--radius-pill); }
.omdome__namn { font-weight: 500; font-size: var(--t-small); }
.betyg { color: var(--accent); font-size: 0.75rem; letter-spacing: 0.18em; }

/* ---------- Fördelar: ikon + etikett + text ----------------- */

/* Ikonerna ska vara HÅRFINA linjer, stroke 1–1.5. Fyllda ikoner
   och emoji är två av de säkraste sätten att se billig ut. */
.formaner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}
.forman__ikon { color: var(--accent); margin-bottom: 1.1rem; }
.forman__ikon svg { width: 34px; height: 34px; stroke-width: 1.2; }
.forman__titel {
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  font-weight: 500;
  margin-bottom: 0.7rem;
}
.forman p { font-size: var(--t-small); color: var(--ink-soft); }

/* ---------- Öppettider -------------------------------------- */

.oppettider { display: grid; gap: 0; max-width: 420px; }
.oppettider__rad {
  display: flex; justify-content: space-between; gap: 1.5rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--line);
  font-size: var(--t-small);
}
.oppettider__tid { color: var(--accent); font-variant-numeric: tabular-nums; }
.oppettider__rad--stangt .oppettider__tid { color: var(--ink-soft); }
.pa-morkt .oppettider__rad, .band--mork .oppettider__rad { border-color: var(--line-on-dark); }
.pa-morkt .oppettider__tid, .band--mork .oppettider__tid { color: var(--accent-on-dark); }

/* ---------- Formulär ---------------------------------------- */

/* Understruket fält, ingen ruta. Rutor gör formuläret till en
   myndighetsblankett; linjen gör det till en anteckning. */
.falt { display: grid; gap: 0.4rem; }
.falt label {
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.falt input, .falt select, .falt textarea {
  font-family: var(--font-body);
  font-size: var(--t-body);
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  padding: 0.75rem 0;
  transition: border-color var(--t-fast) var(--ease);
}
.falt input:focus, .falt select:focus, .falt textarea:focus {
  outline: none;
  border-bottom-color: var(--accent);
}
.falt textarea { resize: vertical; min-height: 7rem; }
.faltrad {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

/* ---------- Logotypremsa ------------------------------------ */

/* Produktmärkena salongen faktiskt säljer. Gråskala tills man för
   muspekaren över — annars slåss sex olika märkesfärger med temat. */
.logorad {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}
.logorad img {
  height: clamp(20px, 2.4vw, 30px);
  width: auto;
  filter: grayscale(1);
  opacity: 0.5;
  transition: opacity var(--t-slow) var(--ease), filter var(--t-slow) var(--ease);
}
.logorad img:hover { filter: grayscale(0); opacity: 1; }

/* ---------- Sidfot ------------------------------------------ */

.sidfot {
  background: var(--surface);
  color: var(--surface-ink);
  padding-block: var(--section-y) 0;
}
.sidfot__rutnat {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
}
@media (max-width: 780px) { .sidfot__rutnat { grid-template-columns: 1fr; } }
.sidfot__pastaende {
  font-family: var(--font-display);
  font-size: var(--t-h2);
  line-height: var(--display-leading);
  letter-spacing: var(--display-tracking);
  text-transform: var(--display-case);
  color: #fff;
}
.sidfot__pastaende em { font-style: normal; color: var(--accent-on-dark); }
[data-tema="varm-modern"] .sidfot__pastaende em,
[data-tema="redaktionell"] .sidfot__pastaende em { font-style: italic; color: inherit; }
.sidfot h3 {
  font-family: var(--font-body);
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--accent-on-dark);
  margin-bottom: 1.4rem;
}
.sidfot__lankar { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.85rem; }
.sidfot__lankar a { text-decoration: none; font-size: var(--t-small); color: var(--surface-soft); }
.sidfot__lankar a:hover { color: var(--accent-on-dark); }
.sidfot__botten {
  margin-top: var(--section-y-tight);
  padding-block: 1.6rem;
  border-top: 1px solid var(--line-on-dark);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem;
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--surface-soft);
}

/* ============================================================
   UNDERSIDOR
   ------------------------------------------------------------
   Härlett ur Cassinis åtta undersidor, renderade ur Figma
   2026-07-31. Se referenser/cassini-undersidor.md.

   Fram till nu hade mallen bara startsidor. Det är därför den
   inte kunde leverera en kundsajt — en salong utan sidan
   "Öppettider och hitta hit" är inte en sajt, det är en affisch.
   ============================================================ */

/* ---------- Kontaktrutnät ----------------------------------- */

/* Cassini låter rubriken bära hela vänsterhalvan ensam och
   trycker ihop tre smala kolumner till höger. Det ser avsiktligt
   ut på ett sätt som fyra jämnbreda kolumner aldrig gör. */
.kontaktrutnat {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.kontaktrutnat__kolumner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.kontaktrutnat h3 {
  font-family: var(--font-body);
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: 0.01em;
  text-transform: none;
  margin-bottom: 1rem;
}
.kontaktrutnat ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.kontaktrutnat li, .kontaktrutnat p { font-size: var(--t-small); color: var(--ink-soft); }
.kontaktrutnat a { text-decoration: none; }
.kontaktrutnat a:hover { color: var(--accent); }
@media (max-width: 800px) { .kontaktrutnat { grid-template-columns: 1fr; } }

/* Sociala ikoner — hårfina, aldrig fyllda märkesloggor i färg. */
.sociala { display: flex; gap: 1.1rem; margin-top: 1.2rem; }
.sociala a { color: var(--ink-soft); transition: color var(--t-fast) var(--ease); }
.sociala a:hover { color: var(--accent); }
.sociala svg { width: 18px; height: 18px; }
.pa-morkt .sociala a, .band--mork .sociala a { color: var(--surface-soft); }
.pa-morkt .sociala a:hover, .band--mork .sociala a:hover { color: var(--accent-on-dark); }

/* ---------- Karta ------------------------------------------- */

/* ALDRIG en inbäddad Google-karta. En <iframe> till maps.google.com
   är ett tredjepartsanrop som läcker besökarens IP innan hen ens
   klickat — samma skäl som att fonterna självhostas (regel 5).

   Vi lägger en statisk bild i full bredd med en länk ovanpå. Samma
   yta, samma funktion, noll anrop. Bilden exporteras en gång vid
   bygget och ligger i img/. */
.karta {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 5;
  overflow: hidden;
  background: var(--paper-alt);
}
.karta img { width: 100%; height: 100%; object-fit: cover; filter: grayscale(1) contrast(1.05); }
.karta__nal {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -100%);
  width: 34px; height: 34px;
  color: var(--accent);
  filter: drop-shadow(0 3px 8px rgba(0,0,0,.35));
}
.karta__etikett {
  position: absolute; left: clamp(1rem, 4vw, 3rem); bottom: clamp(1rem, 3vw, 2rem);
  background: var(--paper);
  color: var(--ink);
  padding: 0.9rem 1.4rem;
  font-size: var(--t-small);
  border: 1px solid var(--line);
}
@media (max-width: 700px) { .karta { aspect-ratio: 4 / 3; } }

/* Utan egen exteriörbild.
   ------------------------------------------------------------
   En genererad husfasad blir nästan alltid fel stad, fel arkitektur
   och ofta en skylt med påhittad text — och kartan visar en riktig
   adress bredvid, så en påhittad fasad blir en direkt osanning.

   En LÅNAD fasad är värre: mallens platshållare har en annan
   verksamhets namn tryckt på huset.

   Tills kunden fotograferat sin egen entré: tonad platta med nålen
   och adressen, centrerat. Ser avsiktligt ut och ljuger inte. */
.karta--utan-bild {
  aspect-ratio: 16 / 6;
  display: grid;
  place-items: center;
  gap: 0.9rem;
  background:
    repeating-linear-gradient(90deg, transparent 0 78px, var(--line) 78px 79px),
    repeating-linear-gradient(0deg, transparent 0 78px, var(--line) 78px 79px),
    var(--paper-alt);
  text-decoration: none;
}
.karta--utan-bild .karta__nal {
  position: static;
  transform: none;
  filter: none;
}
.karta--utan-bild .karta__etikett {
  position: static;
  background: transparent;
  border: 0;
  text-align: center;
  padding: 0;
}
@media (max-width: 700px) { .karta--utan-bild { aspect-ratio: 3 / 2; } }

/* ---------- Grupperade frågor ------------------------------- */

/* Tolv frågor i en enda lista läser som ett formulär. Samma tolv
   under två rubriker läser som sorterade. Cassini grupperar alltid.
   Måttet hålls smalt — läsbarhet före bredd. */
.faq-grupp + .faq-grupp { margin-top: clamp(3rem, 6vw, 5rem); }
/* Gruppubriken är en RUBRIK, inte en etikett. Skrivs den i .h3 blir
   den brödtextsnitt i blandad skrift och läser som en liten fetstil —
   Cassini kör dem stora i displaysnittet, och det är skillnaden mellan
   "sorterade frågor" och "en lista med mellanrum".

   --t-h2 och inte --t-h3: den senare är avstämd för brödtextsnitt och
   ligger under 2rem, vilket gör hårfina serifer som Italiana gråtunna.
   Varje tema har redan ett säkert golv i --t-h2.

   Följden är att sidan inte ska ha en egen h2 direkt ovanför — då
   konkurrerar två lika stora rubriker. På en frågesida är GRUPPEN
   rubriken. */
.faq-grupp__titel {
  text-align: center;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
  font-family: var(--font-display);
  font-size: var(--t-h2);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-transform: var(--display-case);
  line-height: var(--display-leading);
}

/* Öppen fråga får accentfärg. Det är hela skillnaden mot att bara
   fälla ut ett svar — man ser vilken rad man står på. */
.dragspel__knapp[aria-expanded="true"] { color: var(--accent); }

/* ---------- Formulär: bredd och centrerad knapp ------------- */

.falt--full { grid-column: 1 / -1; }
.formular__botten { margin-top: 2rem; text-align: center; }
.formular__villkor {
  margin: 1.5rem auto 0;
  max-width: 52ch;
  font-size: var(--t-label);
  line-height: 1.6;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink-soft);
  text-align: center;
}

/* ---------- Felsida ----------------------------------------- */

/* Cassinis 404 är helskärm utan sidfot: foto, jättesiffra i låg
   opacitet, rubrik ovanpå, en konturknapp. Ingen navigation ut
   utom hem — en 404 ska vara en återvändsgränd med en dörr. */
.felsida {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  background: var(--surface);
  color: var(--surface-ink);
  overflow: hidden;
}
.felsida__bild {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.42;
}
.felsida__innehall { position: relative; padding: var(--gutter); }
.felsida__tal {
  font-family: var(--font-display);
  font-size: clamp(7rem, 26vw, 18rem);
  line-height: 0.85;
  letter-spacing: 0.02em;
  color: #fff;
  opacity: 0.28;
  margin: 0;
}
/* Rubriken ligger ÖVER siffran, inte under. Överlappet är greppet —
   utan det är det bara två rader text. */
.felsida__titel {
  margin-top: -0.34em;
  position: relative;
  color: #fff;
}
.felsida .btn { margin-top: clamp(1.75rem, 4vw, 2.75rem); }
.felsida__botten {
  position: absolute; left: 0; right: 0; bottom: clamp(1rem, 3vw, 2rem);
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--surface-soft);
}

/* ============================================================
   PRIORITET 3 + SYSTEMÄNDRING C
   ============================================================ */

/* ---------- Systemändring C: nivåsystemet ------------------- */

/* Bygglistan #16. Prislistans flikar ÄR frisörnivåer, och samma
   nivå sitter som chip på teamkortet. Priset hänger ihop med
   personen — klickar man "Mästare" tänds Johanna, och klickar man
   Johannas chip hoppar prislistan dit.

   Vi hade flikar utan koppling, vilket är sämre än inga flikar:
   det ser ut att betyda något och gör det inte. */
.team__niva {
  display: inline-flex; align-items: center; gap: 0.45em;
  margin-top: 0.55rem;
  padding: 0.4em 0.9em;
  font-family: var(--font-body);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.team__niva:hover { border-color: var(--accent); color: var(--accent); }
/* Aktiv nivå — sätts av main.js på BÅDA hållen samtidigt. */
.team__kort[data-aktiv="true"] .team__niva {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
/* Kort som inte matchar vald nivå tonas — de försvinner inte.
   Att dölja folk ur teamet när man klickar ett pris läser som en
   bugg; att tona dem läser som ett svar. */
.team[data-filtrerar="true"] .team__kort:not([data-aktiv="true"]) {
  opacity: 0.42;
  transition: opacity var(--t-slow) var(--ease);
}
.pa-morkt .team__niva, .band--mork .team__niva { color: var(--surface-soft); border-color: var(--line-on-dark); }

/* Prisrader som hör till en nivå. Utan JS syns alla — listan är
   fullständig och korrekt även om skriptet aldrig kör. */
/* [hidden] sätts av main.js. Regeln behövs för att .pris__rad är
   display:flex, och display slår [hidden]:s inbyggda display:none. */
.pris__rad[hidden], .pris__beskrivning[hidden] { display: none !important; }

/* ---------- Stjärnbetyg på teamkort (#17) ------------------- */

.team__betyg {
  display: flex; align-items: center; gap: 0.5rem;
  margin-top: 0.5rem;
  font-size: var(--t-small);
  color: var(--ink-soft);
}
.team__betyg .betyg { letter-spacing: 0.1em; }
.team__betyg b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.pa-morkt .team__betyg b, .band--mork .team__betyg b { color: var(--surface-ink); }

/* ---------- Rund teamvariant -------------------------------- */

/* Cassinis Our Team-sida. Cirkulära porträtt, centrerad text.
   Kräver bilder där ansiktet sitter mitt i rutan — en 3:4-bild
   beskuren till cirkel kapar ofta hakan. */
.team--rund { text-align: center; }
.team--rund .team__bild {
  aspect-ratio: 1;
  border-radius: var(--radius-pill);
  max-width: 260px;
  margin-inline: auto;
}
.team--rund .team__niva, .team--rund .team__betyg { justify-content: center; }
.team--rund .team__betyg { display: inline-flex; }

/* ---------- Bildspelssiffror (#18) -------------------------- */

/* Lodrät stapel vid högerkanten. Aktiv siffra inringad, övriga
   bara text. Sett i haires 01 och 03 och i Cassini 01_07. */
.bildspelsnr {
  position: absolute; right: clamp(1rem, 3vw, 2.5rem); top: 50%;
  transform: translateY(-50%);
  display: grid; gap: 0.9rem;
  z-index: 3;
  font-family: var(--font-display);
  font-size: 0.9rem;
  letter-spacing: 0.08em;
}
.bildspelsnr button {
  width: 2.6rem; height: 2.6rem;
  display: grid; place-items: center;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  color: rgba(255,255,255,.55);
  font: inherit;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.bildspelsnr button:hover { color: #fff; }
.bildspelsnr button[aria-current="true"] {
  border-color: rgba(255,255,255,.8);
  color: #fff;
}
@media (max-width: 700px) { .bildspelsnr { display: none; } }

/* ---------- Cirkelpilar vid hero-kanterna (#19) ------------- */

.hero__pil {
  position: absolute; top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: clamp(44px, 4vw, 58px); height: clamp(44px, 4vw, 58px);
  display: grid; place-items: center;
  background: rgba(255,255,255,.09);
  border: 1px solid rgba(255,255,255,.35);
  border-radius: var(--radius-pill);
  color: #fff;
  cursor: pointer;
  transition: all var(--t-fast) var(--ease);
}
.hero__pil:hover { background: rgba(255,255,255,.2); border-color: #fff; }
.hero__pil--vanster { left: clamp(1rem, 3vw, 2.5rem); }
.hero__pil--hoger  { right: clamp(1rem, 3vw, 2.5rem); }
.hero__pil svg { width: 20px; height: 20px; }
@media (max-width: 700px) { .hero__pil { display: none; } }

/* ---------- Förtroendemärke som cirkel (#21) ---------------- */

/* Haires 06. En cirkel med tunn ram, ett litet ord i versaler och
   ett årtal eller en siffra. Fungerar för "Svensk Frisörförening"
   eller "Certifierad kolorist" — aldrig för påhittade utmärkelser. */
.fortroendemarke {
  display: inline-grid;
  place-items: center;
  gap: 0.15rem;
  width: clamp(92px, 11vw, 128px);
  aspect-ratio: 1;
  border: 1px solid var(--accent);
  border-radius: var(--radius-pill);
  text-align: center;
  padding: 0.6rem;
  color: var(--accent);
}
.fortroendemarke b {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  font-weight: var(--display-weight);
  line-height: 1;
}
.fortroendemarke span {
  font-size: 0.5625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--ink-soft);
}
.pa-morkt .fortroendemarke, .band--mork .fortroendemarke { border-color: var(--accent-on-dark); color: var(--accent-on-dark); }
.pa-morkt .fortroendemarke span, .band--mork .fortroendemarke span { color: var(--surface-soft); }
.marken { display: flex; flex-wrap: wrap; gap: clamp(1rem, 2.5vw, 2rem); align-items: center; }

/* ---------- Nivåkort (Cassini 02_04) ------------------------ */

/* Tre mörka kort, mittersta större och lyft. Punkter som INTE
   ingår står kvar men nedtonade — man ska se vad man missar.
   Tre kort med olika många rader säger inte samma sak. */
.nivakort-rad {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: clamp(1rem, 2vw, 1.75rem);
  align-items: center;
}
.nivakort {
  position: relative;
  display: flex; flex-direction: column;
  gap: 1.1rem;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--surface);
  color: var(--surface-ink);
  border: 1px solid var(--line-on-dark);
}
/* Det valda kortet är STÖRRE, inte ljusare. Första försöket gav det
   --paper-alt på ett --paper-alt-band: kortet försvann in i sidan
   i stället för att lyftas ur den. Cassini håller alla tre mörka och
   låter storleken och accentramen göra jobbet. */
.nivakort--vald {
  padding-block: clamp(2.75rem, 5vw, 4.25rem);
  padding-inline: clamp(2rem, 3.5vw, 3rem);
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}
.nivakort__namn { font-size: var(--t-h3); }
.nivakort__valetikett {
  font-family: var(--font-body);
  font-size: var(--t-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin-left: 0.7em;
}
.nivakort__belopp {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 2.6rem);
  line-height: 1;
  color: var(--accent-on-dark);
}
.nivakort--vald .nivakort__belopp { font-size: clamp(2.2rem, 4vw, 3.1rem); }
.nivakort ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.nivakort li {
  display: grid; grid-template-columns: 1em 1fr; gap: 0.75rem;
  font-size: var(--t-small);
  color: var(--surface-soft);
}
.nivakort li::before {
  content: "";
  width: 0.4em; height: 0.4em;
  margin-top: 0.62em;
  border-radius: var(--radius-pill);
  background: var(--accent-on-dark);
}
.nivakort li[data-ingar="nej"] { opacity: 0.38; text-decoration: line-through; text-decoration-thickness: 1px; }
.nivakort li[data-ingar="nej"]::before { background: currentColor; }
.nivakort .btn { margin-top: auto; align-self: start; }
.nivakort .btn--kontur { color: var(--surface-ink); border-color: var(--line-on-dark); }
.nivakort .btn--kontur:hover { border-color: var(--accent-on-dark); color: var(--accent-on-dark); }

/* ---------- Prislista med utspridda foton (Cassini 02_05) --- */

/* Billigaste sättet att rädda sidans tråkigaste sektion: fyra små
   foton på olika höjd runt listan. Inget nytt innehåll, bara något
   att titta på. Döljs under 1100px — där finns ingen marginal att
   lägga dem i, och ovanpå listan blir de skräp. */
.pris--strodd { position: relative; }
.pris__foto {
  position: absolute;
  width: clamp(90px, 9vw, 128px);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  pointer-events: none;
}
/* Procentuella offsets fungerade INTE. -13 % av en 800 px lista är
   104 px, men bilden är 128 px bred — de sista 24 px hamnade ovanpå
   prisnamnen och gjorde raderna oläsbara. Syntes direkt i rendering
   och hade aldrig synts i koden.
   translateX(-100%) flyttar bilden hela sin EGEN bredd, oavsett hur
   bred listan är. Då kan den aldrig gå in över texten. */
.pris__foto--a { left: 0;  top: 3%;     transform: translateX(calc(-100% - 2.5rem)); }
.pris__foto--b { right: 0; top: 24%;    transform: translateX(calc(100% + 2.5rem)); }
.pris__foto--c { left: 0;  bottom: 8%;  transform: translateX(calc(-100% - 2.5rem)); }
/* bottom: 30 % lade --d ovanpå --b när listan var kort. 6 % håller
   dem isär oavsett antal rader. */
.pris__foto--d { right: 0; bottom: 6%; transform: translateX(calc(100% + 2.5rem)); }
/* Under 1250 px finns ingen marginal att lägga dem i. Då är de
   borta — aldrig ovanpå listan. */
@media (max-width: 1250px) { .pris__foto { display: none; } }

/* ---------- Delad helskärm (Cassini 01_07) ------------------ */

.delad-skarm {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100svh;
}
.delad-skarm__text {
  position: relative;
  display: flex; flex-direction: column; justify-content: center;
  gap: 1.5rem;
  padding: clamp(2rem, 6vw, 6rem);
  background: var(--paper);
  overflow: hidden;
}
.delad-skarm__bild { position: relative; overflow: hidden; }
.delad-skarm__bild img { width: 100%; height: 100%; object-fit: cover; }
/* Datarader: etikett i spärrade versaler, värde i brödtext. */
.datarad { display: flex; flex-wrap: wrap; align-items: baseline; gap: 1.5rem; }
.datarad__etikett {
  flex: none;
  min-width: 6.5rem;
  font-size: var(--t-label);
  letter-spacing: var(--label-tracking);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.chipar { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chip {
  padding: 0.5em 1.2em;
  font-size: var(--t-small);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  font-family: var(--font-body);
  transition: all var(--t-fast) var(--ease);
}
.chip[aria-pressed="true"] { border-color: var(--ink); color: var(--ink); }
.delad-skarm__pris {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 2.75rem);
  line-height: 1;
  color: var(--accent);
}
@media (max-width: 900px) {
  .delad-skarm { grid-template-columns: 1fr; min-height: 0; }
  .delad-skarm__bild { aspect-ratio: 4 / 3; }
}

/* ---------- Enskärm (Cassini 01_08) ------------------------- */

/* Den mest extrema layouten i hela materialet. Ett foto, en
   rubrik, en pil. Passar EXAKT en sorts kund: den som har ett
   fantastiskt foto och inget annat. För alla andra är det en tom
   sida — receptet varnar för det. */
.enskarm {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: end;
  overflow: hidden;
  color: #fff;
}
.enskarm__bild { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.enskarm::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,.6) 0%, rgba(0,0,0,.15) 50%, rgba(0,0,0,.35) 100%);
}
.enskarm__innehall {
  position: relative; z-index: 2;
  padding: clamp(2rem, 6vw, 5rem);
  padding-bottom: clamp(4rem, 9vw, 7rem);
}
.enskarm .display { color: #fff; text-shadow: 0 2px 40px rgba(0,0,0,.5); }
/* Enda uppmaningen är en lång tunn pil. Ingen knapp — knappen
   skulle konkurrera med rubriken om samma yta. */
.enskarm__pil {
  display: inline-flex; align-items: center;
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  color: #fff;
  text-decoration: none;
}
.enskarm__pil svg { width: clamp(64px, 8vw, 96px); height: 24px; }
.enskarm__pil:hover svg { transform: translateX(8px); transition: transform var(--t-fast) var(--ease); }
/* Räknaren är två överlappande cirklar, inte prickar i rad. */
.enskarm__raknare {
  position: absolute; right: clamp(1.5rem, 5vw, 4rem); top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: flex; align-items: center;
}
.enskarm__raknare span {
  width: clamp(52px, 6vw, 76px); aspect-ratio: 1;
  display: grid; place-items: center;
  border: 1px solid rgba(255,255,255,.5);
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 1.15rem;
}
.enskarm__raknare span + span { margin-left: -1.1rem; color: rgba(255,255,255,.5); }
.enskarm__botten {
  position: absolute; z-index: 2;
  left: clamp(2rem, 6vw, 5rem); right: clamp(2rem, 6vw, 5rem);
  bottom: clamp(1rem, 2.5vw, 1.75rem);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem;
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.7);
}
@media (max-width: 700px) { .enskarm__raknare { display: none; } }

/* ============================================================
   CASSINI-GREPPEN 23, 24, 27, 29, 30, 31, 32
   ------------------------------------------------------------
   Sista posterna i BYGGLISTA.md. Se cassini-layouter.md och
   cassini-undersidor.md.
   ============================================================ */

/* ---------- 23. Gradientbakgrund ---------------------------- */

/* Cassini kör gradienter där haires kör platta fält. Regeln som
   gör skillnad mellan dyrt och billigt: gradienten går mellan två
   toner som ligger NÄRA varandra. En gradient från beige till
   lila är 2010-talets webbyrå. */
.band--gradient {
  background: linear-gradient(160deg,
    var(--paper) 0%,
    color-mix(in srgb, var(--accent) 12%, var(--paper)) 52%,
    var(--paper-alt) 100%);
}
.band--gradient-mork {
  background: linear-gradient(160deg,
    var(--surface) 0%,
    color-mix(in srgb, var(--accent) 22%, var(--surface)) 58%,
    var(--surface) 100%);
  color: var(--surface-ink);
}

/* ---------- 24. Vriden kortstack (polaroid) ----------------- */

/* Två till tre foton lätt roterade och överlappande. Rotationen
   måste vara LITEN — över 5° läser det som ett misstag i stället
   för ett grepp. Ingen ram, ingen skugga: en vit polaroidkant på
   ett foto i en salong ser ut som en mall. */
.kortstack { position: relative; display: grid; place-items: center; padding: clamp(1rem, 3vw, 2.5rem); }
.kortstack img {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  grid-area: 1 / 1;
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
}
.kortstack img:nth-child(1) { transform: rotate(-4deg) translate(-22%, 4%); }
.kortstack img:nth-child(2) { transform: rotate(2deg); z-index: 2; }
.kortstack img:nth-child(3) { transform: rotate(5deg) translate(22%, -3%); }
@media (max-width: 600px) {
  .kortstack img:nth-child(1), .kortstack img:nth-child(3) { display: none; }
  .kortstack img:nth-child(2) { transform: none; }
}

/* ---------- 27. Lodräta randstaplar ------------------------- */

/* Dekoration i kanten. Tunna lodräta streck med ojämn höjd — det
   är ojämnheten som gör att de inte läser som en laddningsindikator. */
.randstapel {
  display: flex; align-items: flex-end; gap: 5px;
  height: clamp(48px, 7vw, 88px);
  opacity: 0.45;
  pointer-events: none;
}
.randstapel i { display: block; width: 2px; background: var(--accent); }
.randstapel i:nth-child(4n+1) { height: 100%; }
.randstapel i:nth-child(4n+2) { height: 55%; }
.randstapel i:nth-child(4n+3) { height: 78%; }
.randstapel i:nth-child(4n)   { height: 36%; }

/* ---------- 29. Bildtrio med rubrik tvärs över -------------- */

/* Tre överlappande bilder med rubriken lagd RAKT ÖVER dem, i mitten.
   Fungerar bara om rubriken är kort och bilderna mörka nog — därav
   skuggan bakom texten. Cassini 02_01. */
.bildtrio { position: relative; display: grid; place-items: center; padding-block: clamp(1.5rem, 4vw, 3rem); }
.bildtrio__bilder {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(0.75rem, 2vw, 1.5rem);
  width: 100%;
  align-items: center;
}
.bildtrio__bilder img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
/* Mittbilden större — det är den som bär rubriken. */
.bildtrio__bilder img:nth-child(2) { aspect-ratio: 3 / 4.6; }
/* Rubriken behöver en egen mörk platta bakom sig. Första försöket
   litade på text-shadow — och rubriken försvann helt över en ljus
   produktbild i demo-berattande. En bakgrund som "fungerar om
   bilderna är mörka nog" är ingen komponent, det är en förhoppning.
   Plattan gör greppet oberoende av vilket foto kunden har. */
.bildtrio__rubrik {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(100%, 30ch);
  padding: clamp(1.25rem, 3vw, 2.25rem) clamp(1rem, 3vw, 2.5rem);
  text-align: center;
  z-index: 2;
  color: #fff;
  background: rgba(18, 18, 20, 0.46);
  backdrop-filter: blur(3px);
  text-shadow: 0 2px 24px rgba(0,0,0,.6);
  pointer-events: none;
}
.bildtrio__rubrik em { color: var(--accent-foto); }
@media (max-width: 700px) {
  .bildtrio__bilder { grid-template-columns: 1fr; }
  .bildtrio__bilder img:nth-child(1), .bildtrio__bilder img:nth-child(3) { display: none; }
}

/* ---------- 30. Statistik med linje ovanför ----------------- */

/* Cassinis variant: en tunn linje ÖVER varje tal i stället för
   avdelare mellan posterna. Ger en tabellkänsla som passar
   siffror och som en centrerad rad aldrig får. */
.statistik--linje { text-align: left; }
.statistik--linje .statistik__post {
  border-top: 1px solid var(--line-on-dark);
  border-left: 0;
  padding-top: clamp(1rem, 2vw, 1.6rem);
  padding-left: 0;
}
.statistik--linje .statistik__tal { font-variant-numeric: lining-nums tabular-nums; }

/* ---------- 31. Numrering med linje under bilden ------------ */

.numrerade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2.25rem);
}
.numrerad img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.numrerad__rad {
  display: flex; align-items: baseline; gap: 1rem;
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
}
.numrerad__nr {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  color: var(--accent);
  font-variant-numeric: lining-nums;
}
.numrerad__namn { font-size: var(--t-small); }
.pa-morkt .numrerad__rad, .band--mork .numrerad__rad { border-top-color: var(--line-on-dark); }

/* ---------- 32. Ellips i stället för cirkel ----------------- */

/* Bygglistan #32. En smal ellips är mjukare än en cirkel och
   fungerar på stående porträtt där cirkeln kapar hakan. */
.ellipsbild {
  width: 100%;
  max-width: 340px;
  aspect-ratio: 3 / 4.2;
  object-fit: cover;
  border-radius: 50%;
}

/* ============================================================
   HELBILDSHERO — fotot ÄR designen
   ------------------------------------------------------------
   Lagt till efter en jämförelse mot en Base44-genererad
   salongssajt. Den vann på en enda sak: ett stort, proffsigt
   foto i 100vh med typen ovanpå. Palett, typsnittsval och
   rak+kursiv-mixen var identiska med våra.

   Vår egen hero gjorde tvärtom. `hero--delad` ger fotot halva
   skärmen, `hero--typografisk` degraderar det till ett band på
   420 px under texten. Båda byggdes för att våra bilder var
   dåliga — vi designade bort fotot i stället för att skaffa ett
   bättre. Det är det enskilt största misstaget i hela mallen.

   Regeln: har kunden EN bra bild ska den fylla skärmen.
   Har kunden ingen — skaffa en, använd inte en annan hero.
   ============================================================ */
/* CENTRERAT, inte bottenställt. Första försöket låg på
   align-items:end och knapparna hamnade UNDER vikningen — det
   bryter mot den viktigaste heroregeln som finns: uppmaningen
   ska synas utan att scrolla. Syntes direkt i jämförelsen mot
   Base44 och inte alls i koden. */
.hero--helbild {
  min-height: 100svh;
  display: grid;
  align-items: center;
}
.hero--helbild .hero__bild {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* TVÅ gradienter, inte en. Den lodräta ger djup; den vågräta
   lugnar den sida där typen ligger. Ett stökigt foto rakt under
   en rubrik gör rubriken svårläst hur stor den än är — Base44
   har en lugn vänsterhalva och det är därför deras typ sitter. */
.hero--helbild .hero__skugga {
  position: absolute; inset: 0;
  background:
    linear-gradient(to right,
      rgba(0,0,0,.80) 0%,
      rgba(0,0,0,.55) 34%,
      rgba(0,0,0,.12) 66%,
      rgba(0,0,0,.30) 100%),
    linear-gradient(to top,
      rgba(0,0,0,.55) 0%,
      rgba(0,0,0,.10) 40%,
      rgba(0,0,0,.30) 100%);
}
.hero--helbild .hero__innehall { padding-block: clamp(2rem, 5vw, 4rem); }

/* Hela textblocket får en egen rytm. Utan den klumpar ögonbryn,
   rubrik, brödtext och knappar ihop sig mot varandra. */
.hero--helbild .hero__innehall .wrap > * + * { margin-top: clamp(1rem, 2vw, 1.6rem); }
.hero--helbild .script { display: block; margin-bottom: .2em; }

/* Rubriken får ta plats — men 8vw, inte 9. Vid 9 sprängde
   "SEX KUNDER" mätet och tvingade ut resten ur vikningen. */
.hero--helbild .display {
  font-size: clamp(2.6rem, 8vw, 6.5rem);
  max-width: 14ch;
}
.hero--helbild .lede {
  max-width: 40ch;
  color: rgba(255,255,255,.86);
}
.hero--helbild .hero__knappar { margin-top: clamp(1.6rem, 3vw, 2.5rem); }

/* Rörelsen: EN sak, motiverad. Rubriken och knapparna kommer in
   underifrån vid laddning, i sekvens. Det ger sidan en riktning
   i stället för att bara existera.
   Kräver .js — utan skript syns allt direkt. */
html.js .hero--helbild .hero__innehall > .wrap > * {
  opacity: 0;
  transform: translateY(22px);
  animation: heroIn .9s cubic-bezier(.16,1,.3,1) forwards;
}
html.js .hero--helbild .hero__innehall > .wrap > *:nth-child(1) { animation-delay: .10s; }
html.js .hero--helbild .hero__innehall > .wrap > *:nth-child(2) { animation-delay: .20s; }
html.js .hero--helbild .hero__innehall > .wrap > *:nth-child(3) { animation-delay: .32s; }
html.js .hero--helbild .hero__innehall > .wrap > *:nth-child(4) { animation-delay: .44s; }
@keyframes heroIn { to { opacity: 1; transform: none; } }

/* Långsam inzoomning på fotot. 12 sekunder, 4 procent — så
   lite att man inte ser den hända, bara att bilden lever. */
@media (prefers-reduced-motion: no-preference) {
  .hero--helbild .hero__bild { animation: heroZoom 14s ease-out forwards; }
  @keyframes heroZoom { from { transform: scale(1.04); } to { transform: scale(1); } }
}
@media (prefers-reduced-motion: reduce) {
  html.js .hero--helbild .hero__innehall > .wrap > * { opacity: 1; transform: none; animation: none; }
}

/* ---------- Hoppa till innehållet --------------------------- */

/* Första fokuserbara elementet på varje sida. Utan den måste den
   som navigerar med tangentbord tabba genom hela sidhuvudet på
   varje undersida. Syns bara vid fokus. */
.hoppa {
  position: absolute;
  left: -9999px;
  z-index: 100;
  padding: 0.9em 1.4em;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
}
.hoppa:focus { left: 1rem; top: 1rem; }

/* ---------- GHL-bokning med samtyckesgrind ------------------ */

/* Rutan ska se ut som bokningen redan finns där — annars läser
   den som ett fel. Samma yta, samma ram, samma plats. Se js/ghl.js
   för varför den inte laddar direkt. */
.ghl-ruta {
  border: 1px solid var(--line);
  background: var(--paper-alt);
  min-height: 420px;
  display: grid;
  place-items: center;
  padding: clamp(1.5rem, 4vw, 3rem);
}
.ghl-grind { display: grid; justify-items: center; gap: 1.25rem; text-align: center; max-width: 44ch; }
.ghl-grind__text { font-size: var(--t-small); color: var(--ink-soft); }
.ghl-grind__lank {
  font-size: var(--t-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.ghl-ram { width: 100%; min-height: 620px; border: 0; display: block; }
.ghl-fallback { display: grid; gap: 0.9rem; justify-items: center; text-align: center; }
.ghl-fallback[hidden] { display: none; }
.ghl-status {
  margin-top: 1.25rem;
  font-size: var(--t-small);
  color: var(--accent);
}
.ghl-status[hidden] { display: none; }

/* ---------- Rörelse: sektioner tonar in -------------------- */

/* Enda scroll-effekten på hela sajten. Sätts av main.js via
   IntersectionObserver. Utan JS syns allt direkt — aldrig en sida
   som är osynlig om skriptet inte laddar. */
/* KRITISKT: intoningen får bara gömma innehåll när JavaScript
   bevisligen kör. main.js sätter .js på <html> som allra första
   sats. Utan den gardering blir hela sidan OSYNLIG om skriptet
   inte laddar, blockeras eller hinner köra — och sidan såg
   fullständigt tom ut i den första sida-vid-sida-renderingen.

   Regeln "sajten ska fungera utan skriptet" fanns redan skriven i
   main.js. Den var inte implementerad här. */
html.js .in {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
html.js .in.syns { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  html.js .in { opacity: 1; transform: none; transition: none; }
}
