/* ==========================================================================
   Poetens hjärta

   Rå, inte prydlig. Obleksmutsigt papper, oxblod och nästan svart bläck.
   Typografin är fet grotesk mot maskinskrift, aldrig kalligrafi. Texten
   lägger sig över bilden i stället för att ställa sig snällt under den.
   Rörelserna klipper och glider - inga studsar, inget som pillar.
   ========================================================================== */

:root {
  /* Papper. Kallare och smutsigare än linne. */
  --papper: #eae7e0;
  --papper-djup: #d8d3c9;

  /* Bläck */
  --black: #16130f;
  --black-ljus: #6a635a;

  /* Oxblod. Intorkat, inte färskt. */
  --blod: #6e1014;
  --blod-djup: #470a0d;
  /* Oxblod som syns mot svart. */
  --blod-ljus: #a8383d;

  /* Mörkret på sluthero:t. Uppmätt ur målningens nederkant, så att skarven
   * mellan bild och kod inte syns. */
  --natt: #020406;

  --maskin: 'Space Mono', 'Courier New', monospace;

  --sidhuvud-hojd: 4rem;
  /* Nästan linjär. Rörelsen ska kännas mekanisk, inte omfamnande. */
  --rak: cubic-bezier(0.2, 0, 0.1, 1);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

/* Sidan själv rullar aldrig - det gör .rulle. Utan det här kan en mobil
 * webbläsare låta hela sidan glida i sidled. */
html,
body {
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  margin: 0;
  background: var(--papper);
  color: var(--black);
  font-family: var(--maskin);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Kornet ligger överst över allt och gör ytan ojämn. Utan det blir de stora
 * pappersfälten för rena och sidan ser digital ut. */
.korn {
  position: fixed;
  inset: -50%;
  z-index: 90;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'>\
<filter id='b'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/>\
<feColorMatrix type='saturate' values='0'/></filter>\
<rect width='180' height='180' filter='url(%23b)'/></svg>");
}

/* --- Oljeduken ----------------------------------------------------------- */

/* En målning med tjock, sprucken oljefärg i gråbrunt och svart bakom
 * korthögen. Den ligger fast och rör sig inte: startsidan glider upp och
 * avslöjar den, och Ättestupa glider över den. Kanterna mörknar, så att
 * ljuset samlas kring korten. Mindre skärmar får en mindre fil. */
/* Ramen är exakt skärmen och klipper allt utanför. Själva målningen ligger i
 * ::before och är större än skärmen - utan klippningen kan en mobil
 * webbläsare låta sidan scrolla i sidled ut över den. */
.oljeduk {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.oljeduk::before {
  content: '';
  position: absolute;
  /* Suddig, så att målningen ligger som en stämning bakom korten och inte
   * tävlar med dem. Lagret sträcker sig förbi skärmkanten, annars tonar
   * suddigheten ut kanterna mot den ljusa botten under. */
  inset: -3rem;
  filter: blur(4px);
  pointer-events: none;
  background:
    radial-gradient(ellipse 80% 75% at 50% 47%, rgba(10, 9, 8, 0) 45%, rgba(10, 9, 8, 0.45) 100%),
    #1c1b1a url("../img/bakgrund/olja-1717.jpg") center / cover no-repeat;
}
@media (max-width: 900px) {
  .oljeduk::before {
    background-image:
      radial-gradient(ellipse 80% 75% at 50% 47%, rgba(10, 9, 8, 0) 45%, rgba(10, 9, 8, 0.45) 100%),
      url("../img/bakgrund/olja-1280.jpg");
  }
}

/* --- Rullningen ---------------------------------------------------------- */

.rulle {
  /* Positionerad, så att fästenas offsetTop räknas från rullningens topp. */
  position: relative;
  height: 100dvh;
  /* Bara lodrätt. Ett kort som lutar när det glider in får aldrig göra
   * sidan bredare än skärmen. */
  overflow-x: hidden;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
}
/* Från Ättestupa och nedåt rullar sidan fritt: mörkret och foten läses som en
 * vanlig sida, inte i hopp. Klassen sätts av js/app.js när sluthero:t är
 * framme, och tas bort när man rullar upp till dikterna igen. */
.rulle.fri { scroll-snap-type: none; }
.rulle::-webkit-scrollbar { display: none; }

.dikt {
  position: relative;
  height: 100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  overflow: hidden;
  background: var(--papper-djup);
}

.dikt picture {
  display: block;
  height: 100%;
  opacity: 0;
  transition: opacity 0.5s var(--rak);
}
.dikt.ar-synlig picture { opacity: 1; }

.dikt__bild {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Knappt märkbar glidning. Ingen zoom fram och tillbaka - det ser
   * tillgjort ut. */
  animation: glid 40s linear infinite alternate;
}

@keyframes glid {
  from { transform: scale(1.04) translate3d(-0.8%, 0, 0); }
  to   { transform: scale(1.04) translate3d(0.8%, 0, 0); }
}

/* --- Korthögen ----------------------------------------------------------- */

/* Dikterna är papperskort i en hög. Varje dikt fastnar i överkanten och står
 * kvar mitt på skärmen, och nästa glider upp och lägger sig ovanpå. Bilden
 * visas hel, i sin egen storlek - den krymps bara om skärmen är för liten,
 * och beskärs aldrig.
 *
 * js/app.js sätter två tal på varje kort medan man rullar: --in går från 0
 * till 1 när kortet glider upp, --ut från 0 till 1 när nästa kort täcker det.
 * Kortet på väg upp släpar efter rullningen och lutar mer, och rätar upp sig
 * när det landar. Kortet under sjunker en aning och mörknar i skuggan. */
.dikt__faste {
  /* Upptar ingen plats: den negativa marginalen drar upp kortet efter. */
  height: 100dvh;
  margin-bottom: -100dvh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  pointer-events: none;
}

.dikt[data-nr] {
  /* Luften runt kortet. Till höger måste den räcka för grenen, nedtill för
   * bubblan som sticker ut under hörnet. Är sidorna olika breda flyttar
   * padding-right mitten, så att kortet ändå får rätt luft på båda sidor. */
  --kant-vanster: clamp(3rem, 7vw, 6rem);
  --kant-hoger: var(--kant-vanster);
  --kant-y: 4.5rem;
  padding-right: calc(var(--kant-hoger) - var(--kant-vanster));
  --in: 1;
  --ut: 0;
  position: sticky;
  top: 0;
  display: grid;
  place-items: center;
  overflow: visible;
  background: none;
  scroll-snap-align: none;
  /* Sektionen täcker hela skärmen men är genomskinlig. Bara kortet tar emot
   * klick, annars skulle kortet överst skymma knapparna på korten under. */
  pointer-events: none;
  /* Kortet överst ligger rakt. Lutningen kommer först när nästa kort täcker
   * det, och kortet på väg upp rätar upp sig när det landar. Ett snett kort
   * ritas om pixel för pixel och texten i bilden blir suddig - det som läses
   * ska därför alltid ligga rakt. */
  transform:
    translate3d(0, calc((1 - var(--in)) * 18vh - var(--ut) * 2.5vh), 0)
    scale(calc(1 - var(--ut) * 0.035))
    rotate(calc(var(--ut) * var(--vinkel, 0deg) + (1 - var(--in)) * var(--sving, 0deg)));
}
/* Vilande kort får ingen transform alls. Då ritas bilden direkt i sin egen
 * storlek, utan eget lager som webbläsaren skalar. */
.dikt[data-nr].ar-vilar { transform: none; }
.dikt[data-nr].ar-begravd { visibility: hidden; }

.dikt[data-nr] .dikt__kort {
  height: auto;
  pointer-events: auto;
}

/* Lutningen mot muspekaren. js/app.js sätter vinklarna och .ar-lutar på
 * kortet överst. Övergången gör att kortet följer pekaren med en liten
 * eftersläpning, som om det hade tyngd. Utan .ar-lutar finns ingen
 * transform alls, så ett orört kort ritas lika skarpt som förut. */
.dikt__lutning {
  position: relative;
  pointer-events: auto;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.dikt__lutning.ar-lutar {
  transform: rotateX(var(--luta-x, 0deg)) rotateY(var(--luta-y, 0deg));
}
/* Ett vänt kort läses - där står det stilla. */
.dikt.ar-vand .dikt__lutning { transform: none; }

/* Ljuset. Papper glänser inte - det fångar ljus mjukt och matt. En svag,
 * varm ljusfläck vandrar över kortet när det lutas. Ingen när kortet ligger
 * still, så att bilden syns som den är. Kort som täcks tappar den i skuggan. */
.dikt[data-nr] .dikt__framsida::before {
  content: '';
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 70% 80% at var(--glans-x, 30%) var(--glans-y, 20%),
    rgba(255, 248, 235, 0.14), rgba(255, 248, 235, 0.04) 45%, rgba(255, 248, 235, 0) 75%);
  opacity: calc((1 - var(--in)) * 0.8 * (1 - var(--ut)));
  transition: opacity 0.5s var(--rak);
}
.dikt__lutning.ar-lutar .dikt__framsida::before { opacity: 1; }

/* Skuggan under kortet flyttar sig åt motsatt håll mot pekaren, som om kortet
 * lyfts en aning från högen på den sidan. Ett suddigt block bakom kortet som
 * bara flyttas - suddigheten ritas en gång, inte om vid varje rörelse. */
.dikt__lutning::before {
  content: '';
  position: absolute;
  inset: 3% 4%;
  z-index: -1;
  pointer-events: none;
  background: rgba(22, 19, 15, 0.45);
  filter: blur(22px);
  opacity: 0;
  transform: translate3d(var(--skugga-x, 0px), var(--skugga-y, 10px), -1px);
  transition: opacity 0.6s var(--rak), transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1);
}
.dikt__lutning.ar-lutar::before { opacity: 1; }
.dikt.ar-vand .dikt__lutning::before { opacity: 0; }

.dikt[data-nr] .dikt__framsida {
  position: relative;
  inset: auto;
  height: auto;
}

.dikt[data-nr] picture {
  position: relative;
  height: auto;
  /* Ingen intoning. Kortet glider redan in, och en tonande bild låter
   * kortet under skymta igenom tills toningen är klar. */
  transition: none;
}
/* Tills bilden kommit syns inget - annars ritar webbläsaren alt-texten i en
 * liten ruta mitt på skärmen. .ar-laddad sätts av js/app.js. */
.dikt[data-nr]:not(.ar-laddad) picture { opacity: 0; }

/* Toningen: kortet mörknar mot kanterna och är ljust i mitten, som ett
 * gammalt fotografi. Den ligger i bilden och tonas in med den. Justera
 * mörkret med de två sista alfavärdena, och hur stor den ljusa mitten är
 * med det första procenttalet. */
.dikt[data-nr] picture::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* closest-side: ellipsen når kortets kanter vid 100 %, så att även
   * kanternas mitt blir mörk och inte bara hörnen. */
  background: radial-gradient(ellipse closest-side at 50% 50%,
    rgba(22, 19, 15, 0) 40%,
    rgba(22, 19, 15, 0.28) 78%,
    rgba(22, 19, 15, 0.6) 100%);
}

.dikt[data-nr] .dikt__bild {
  width: auto;
  height: auto;
  max-width: calc(100vw - var(--kant-vanster) - var(--kant-hoger));
  max-height: calc(100dvh - 2 * var(--kant-y));
  animation: none;
  /* Tunt papper: en ljus kant och en mjuk skugga mot kortet under. Ytterst
   * ett svagt, varmt sken, som om kortet fångade ljus i det mörka rummet.
   * Skenet ligger i bildens egen skugga och inte i ett eget lager: ett lager
   * bakom kortet hamnar i samma 3D-rum som vändningen och kan få korten att
   * ritas halvgenomskinliga. */
  box-shadow:
    0 0 0 1px rgba(22, 19, 15, 0.08),
    0 1px 2px rgba(22, 19, 15, 0.18),
    0 14px 34px -10px rgba(22, 19, 15, 0.45),
    0 0 18px 1px rgba(236, 226, 204, 0.1),
    0 0 70px 6px rgba(236, 226, 204, 0.14);
}

/* Skuggan från kortet ovanpå. Opacitet, så att den inte ritas om varje bildruta. */
.dikt[data-nr] .dikt__framsida::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--black);
  opacity: calc(var(--ut) * 0.22);
  pointer-events: none;
}

.dikt[data-nr] .dikt__baksida {
  box-shadow:
    0 0 0 1px rgba(22, 19, 15, 0.08),
    0 14px 34px -10px rgba(22, 19, 15, 0.45),
    0 0 18px 1px rgba(236, 226, 204, 0.1),
    0 0 70px 6px rgba(236, 226, 204, 0.14);
}

/* På kortets baksida behövs ingen extra plats för bubblan - kortet ligger
 * redan innanför den. */
.dikt[data-nr] .kort {
  width: 100%;
  padding: clamp(1rem, 3vw, 1.75rem);
}

@media (max-width: 700px) {
  /* Liggande dikter utan stående bild: kortet får luft runt sig, smalt till
   * vänster och bredare till höger där grenen står. */
  .dikt[data-nr] {
    --kant-vanster: 1rem;
    --kant-hoger: 2.25rem;
    --kant-y: 2.5rem;
  }
  .dikt[data-nr] .kort { padding-right: clamp(1rem, 3vw, 1.75rem); }

  /* Dikter med stående bild fyller hela telefonens skärm. Bilden beskärs
   * lite i kanterna i stället för att lämna tomma band - dikttexten står i
   * mitten av bilden och påverkas inte. data-staende sätts av js/app.js. */
  /* Ett kort som fyller skärmen kan inte luta eller krympa - då syns hörn
   * och kanter snett, och kortet sticker ut på sidorna. Det glider bara
   * rakt upp, och kortet under mörknar. Bredden är låst till skärmen. */
  .dikt[data-nr]:not([data-staende="nej"]) {
    padding: 0;
    transform: translate3d(0, calc((1 - var(--in)) * 18vh), 0);
  }
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__lutning {
    /* Ingen overflow: hidden här - den plattar till 3D-lagret, och då vänds
     * kortet utan djup. Klippningen sköts av .rulle. */
    width: 100%;
    max-width: 100%;
    height: 100%;
  }
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__kort,
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__framsida,
  .dikt[data-nr]:not([data-staende="nej"]) picture {
    width: 100%;
    height: 100%;
  }
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__bild {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    object-fit: cover;
    box-shadow: none;
  }
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__baksida { box-shadow: none; }
  /* Kommentarerna: luft för grenen till höger och telefonens egna kanter. */
  .dikt[data-nr]:not([data-staende="nej"]) .kort {
    padding: calc(1.5rem + env(safe-area-inset-top, 0px)) 2.75rem
             calc(5rem + env(safe-area-inset-bottom, 0px)) 1.25rem;
  }
  /* Tändningen. När ett kort glider in är mitten mörk, och när det landat
   * tänds mitten långsamt medan kanterna förblir mörka - som när ögat vänjer
   * sig vid ljuset på ett blad. Två lager: en mörk slöja över mitten som
   * tonas bort, och ett varmt ljus i mitten som tonas fram strax efter.
   * .ar-framme sätts av js/app.js när kortet är minst 92 % på plats och
   * inget annat kort täcker det - inte först när snäppet är helt klart, som
   * på en telefon dröjer. Tändningen går mjukt, släckningen fort, så att
   * mitten redan är mörk när nästa kort glider över. */
  .dikt[data-nr] picture::before {
    content: '';
    position: absolute;
    z-index: 1;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(ellipse 75% 60% at 50% 48%,
      rgba(8, 6, 5, 0.42), rgba(8, 6, 5, 0.3) 45%, rgba(8, 6, 5, 0) 85%);
    opacity: 1;
    transition: opacity 0.35s var(--rak);
  }
  .dikt[data-nr].ar-framme picture::before {
    opacity: 0;
    transition: opacity 0.9s cubic-bezier(0.3, 0, 0.2, 1);
  }
  /* Ljuset är släckt tills kortet landat - på dator glimmar det i stället
   * när kortet glider in, men här ska mitten vara mörk på vägen upp. */
  .dikt[data-nr] .dikt__framsida::before {
    background: radial-gradient(ellipse 65% 50% at 50% 46%,
      rgba(255, 242, 218, 0.2), rgba(255, 242, 218, 0.07) 45%, rgba(255, 242, 218, 0) 78%);
    opacity: 0;
    transition: opacity 0.35s var(--rak);
  }
  .dikt[data-nr].ar-framme .dikt__framsida::before {
    opacity: 1;
    transition: opacity 0.9s cubic-bezier(0.3, 0, 0.2, 1) 0.05s;
  }

  /* Kantoskärpan: en smal, gradvis oskärpa i kortets över- och underkant.
   * Lagren byggs av js/app.js (byggKant). Den ligger i sektionen, ovanpå
   * kortet, och inte inuti kortet: kortets preserve-3d, som vändningen
   * behöver, stänger av backdrop-filter för allt inuti. Därför bara på kort
   * som fyller skärmen - där sammanfaller sektionens kanter med kortets.
   * Kort som är helt täckta av nästa kort, och vända kort, ritar den inte. */
  .dikt__kant { display: none; }
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__kant {
    display: block;
    position: absolute;
    z-index: 2;
    left: 0;
    right: 0;
    height: 3.5rem;
    pointer-events: none;
    /* Ingen isolation eller overflow här. Lagrens backdrop-filter suddar det
     * som ligger bakom dem inom närmaste isolerade låda - isoleras kanten
     * suddar lagren bara kantens eget, tomma innehåll och inget syns. */
  }
  .dikt__kant--topp { top: 0; }
  .dikt__kant--botten { bottom: 0; }
  .dikt__kant > div {
    position: absolute;
    inset: 0;
  }
  .dikt[data-nr].ar-tackt .dikt__kant,
  .dikt[data-nr].ar-begravd .dikt__kant,
  .dikt[data-nr].ar-vand .dikt__kant { display: none !important; }

  /* Bubblan kan inte sticka ut utanför skärmen - den sitter innanför hörnet,
   * strax ovanför kantoskärpan så att den inte själv blir suddig. */
  .dikt[data-nr]:not([data-staende="nej"]) .dikt__lutning > .bubbla {
    right: 1rem;
    bottom: calc(3.75rem + env(safe-area-inset-bottom, 0px));
  }
}

@media (prefers-reduced-motion: reduce) {
  .dikt[data-nr] { transform: none; }
}

/* --- Diktkortet ---------------------------------------------------------- */

/* Varje dikt är ett kort som vänds kring sin lodräta mittlinje: bilden på
 * framsidan, kommentarerna på baksidan. js/gastbok.js sätter .ar-vand när
 * pratbubblan trycks, och bygger baksidan första gången.
 *
 * Den sida som vetter bort döljs med backface-visibility. Klick går ändå
 * igenom en dold sida i en del webbläsare, därför stängs den också av med
 * pointer-events - och med inert från skriptet, för tangentbordet. */
/* Bara dikterna. Start- och sluthero:t är också .dikt, och perspective
 * hade gjort dem till ett eget lager - då blandas blodet på titeln inte
 * längre mot pappret. */
.dikt[data-nr] { perspective: 2400px; }

.dikt__kort {
  position: relative;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform 0.9s cubic-bezier(0.45, 0.05, 0.2, 1);
}
.dikt.ar-vand .dikt__kort { transform: rotateY(180deg); }

.dikt__framsida,
.dikt__baksida {
  position: absolute;
  inset: 0;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}
.dikt__framsida { height: 100%; }

.dikt__baksida {
  overflow: hidden;
  background: var(--papper);
  transform: rotateY(180deg);
}
.dikt:not(.ar-vand) .dikt__baksida,
.dikt.ar-vand .dikt__framsida { pointer-events: none; }

/* Diktens bild skymtar spegelvänd genom baksidan, som genom tunt papper.
 * Adressen sätts av skriptet. */
.kort__skugga {
  position: absolute;
  inset: -3rem;
  background-position: center;
  background-size: cover;
  transform: scaleX(-1);
  filter: blur(28px) saturate(0.5);
  opacity: 0.22;
  pointer-events: none;
}

/* Innehållet: rubrik överst, kommentarerna som rullar, formuläret nederst.
 * Nedtill lämnas plats för pratbubblan. */
.kort {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(40rem, 100%);
  height: 100%;
  margin: 0 auto;
  padding: calc(var(--sidhuvud-hojd) + 0.75rem) clamp(1.25rem, 5vw, 2.5rem)
           calc(clamp(1.25rem, 4vh, 2rem) + 6rem);
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-weight: 500;
}

.kort__topp {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid var(--blod);
}

.kort__rubrik {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* Antikvans gemena siffror gör ettan till ett litet I bland versalerna. */
  font-variant-numeric: lining-nums;
  color: var(--blod);
}
.kort__rubrik:focus { outline: none; }
.kort__under {
  margin-left: 0.35rem;
  font-style: italic;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--black-ljus);
}

.kort__vand {
  flex: none;
  padding: 0.35rem 0;
  border: 0;
  background: none;
  color: var(--black);
  font: 500 1.05rem/1 "Cormorant Garamond", Georgia, "Times New Roman", serif;
  cursor: pointer;
}
.kort__vand:hover { color: var(--blod); }
.kort__vand:focus-visible {
  outline: 2px solid var(--blod);
  outline-offset: 2px;
}

/* Listan har gästbokens utseende, men rullar inom kortet. overscroll
 * hindrar att rullningen fortsätter ut till nästa dikt när listan är slut. */
.gastbok__lista.kort__lista {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 0 0.25rem 0 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.gastbok__form.kort__form {
  padding: 0.9rem 0 0;
  border-top: 1px solid var(--papper-djup);
  border-bottom: 0;
}
/* Dubbla klasser, eftersom gästbokens formulärregler står längre ned i
 * filen och annars vinner. */
.gastbok__form.kort__form label { margin-bottom: 0.6rem; }
.gastbok__form.kort__form textarea { resize: none; }
.gastbok__form.kort__form .gastbok__besked { margin-top: 0.5rem; }

@media (max-width: 700px) {
  /* Luft till höger, så att grenen i kanten inte skär genom texten. */
  .kort { padding-right: 2.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .dikt__kort { transition: none; }
}

/* --- Starthero ----------------------------------------------------------- */

.start {
  display: grid;
  place-items: center;
  padding: var(--sidhuvud-hojd) 1.5rem 5rem;
  background: var(--papper);
}

.start__inre {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Bildramen runt hjärtat. Som block, så att ingen radhöjd lägger luft under
 * bilden och flyttar titeln. */
.start__hjartbild {
  display: block;
  line-height: 0;
}

.start__hjarta {
  /* Motivet är bara 257 px brett i originalet. Större än så här och det
   * börjar synas att det är uppskalat. */
  width: clamp(6.5rem, 20vw, 9.5rem);
  height: auto;
  /* Ingen mix-blend-mode. Bilden har genomskinlig botten, så inget vitt
   * behöver släckas. Blandningen gav en vit ram i mobilwebbläsare som inte
   * klarar den på en bild som samtidigt animeras och har ett filter. */
  filter: contrast(1.08) saturate(0.92);
  opacity: 0;
  /* Slaget ligger i transform och flyttar inget i layouten, så titeln och
   * blodet under står stilla medan hjärtat dunkar. */
  transform-origin: 50% 55%;
  animation: trada-fram 0.9s var(--rak) 0.1s forwards,
             dunka 1.1s ease-out 1s infinite;
}

@keyframes trada-fram {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Ett riktigt slag är dubbelt: ett kraftigt "dunk" och ett svagare direkt
 * efter, sedan vila. Ungefär 55 slag i minuten - ett lugnt hjärta. */
@keyframes dunka {
  0%   { transform: scale(1); }
  10%  { transform: scale(1.09); }
  20%  { transform: scale(0.99); }
  30%  { transform: scale(1.05); }
  45%  { transform: scale(1); }
  100% { transform: scale(1); }
}

/* Titeln lägger sig över hjärtat i stället för under det. Överlappet är
 * poängen - det ska se ut som tryck på tryck, inte som en bildtext. */
.start__titel {
  /* Titeln är en målad bild. Negativ marginal drar upp den så att den
   * överlappar hjärtat - tryck på tryck, inte bildtext. */
  margin: -2.5% 0 0;
  width: min(88vw, 62rem);
  line-height: 0;
}

.start__titel picture { display: block; }

.start__titel img {
  display: block;
  width: 100%;
  height: auto;
  /* Ingen blandning här. Målningens vita botten är bortnycklad, så den
   * ligger redan fritt mot pappret - och multiply hade släckt glansdagrarna
   * i färgen, som är halva poängen med att den ser våt ut. */
  /* Något mörkare än målningen, så att det klarröda drar sig ner mot
   * oxblodet på resten av sidan. Bloddropparna påverkas inte: js/blod.js
   * läser bildens egna pixlar, och filtret ändrar bara hur den visas. */
  filter: brightness(0.6) saturate(0.95);
  opacity: 0;
  animation: trada-fram 0.8s var(--rak) 0.45s forwards;
}

/* Bloddukens läge sätts av js/blod.js, som mäter upp titeln. Den ligger
 * över titeln men under kornet, och släpper igenom all interaktion. */
.blod {
  position: absolute;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: multiply;
}

/* Dropparna under titeln mörknar lika mycket som den, annars rinner ljusare
 * blod ur mörkare bokstäver. */
.start .blod {
  filter: brightness(0.75);
  /* Blodet tonas in först när titeln syns, annars rinner det ur tomma
   * luften medan bokstäverna fortfarande tonas fram. */
  opacity: 0;
  animation: trada-fram 0.8s var(--rak) 1.1s forwards;
}

.start__namn {
  margin: 2.25rem 0 0;
  /* En antikva under den målade titeln - samma snitt som yoga-sidans
   * rubriker. Mindre spärrning än maskinskriften hade: en antikva faller
   * isär om bokstäverna står för glest. */
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-size: clamp(1.5rem, 2.6vw, 2.3rem);
  font-weight: 500;
  letter-spacing: 0.22em;
  /* Samma indrag som spärrningen, annars hamnar namnet ur mitt: spärrningen
   * läggs efter varje bokstav, även den sista. */
  text-indent: 0.22em;
  text-transform: uppercase;
  /* Något mörkare än den gråa maskinskriften, eftersom snittets tunna linjer
   * annars blir för bleka. */
  color: rgba(22, 19, 15, 0.72);
}

.start__namn span {
  display: inline-block;
  opacity: 0;
  animation: trada-fram 0.6s var(--rak) 1s forwards;
}

/* --- Sluthero ------------------------------------------------------------ */

/* Två skärmar högt: målningen överst, sedan mörker som fortsätter där
 * bilden slutar. Bara överkanten är en snappunkt - därifrån rullar sidan
 * fritt, se .rulle.fri. */
.slut {
  height: auto;
  background: var(--natt);
}

.slut .slut__bild {
  position: relative;
  height: 100dvh;
}

.slut .slut__bild img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 35%;
  /* Något mörkare än originalet, så att målningen sjunker in i mörkret
   * under den i stället för att lysa över det. */
  filter: brightness(0.78);
}

/* På breda skärmar beskärs bildens nederkant, och då slutar den inte längre
 * i svart. Tonen gör att den ändå alltid glider över i mörkret. */
.slut .slut__bild::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 35%;
  background: linear-gradient(to bottom, rgba(2, 4, 6, 0), var(--natt));
  pointer-events: none;
}

/* Korthögen och scenen. På dator finns de bara i HTML: högen släpps ur
 * layouten, så att korten ligger kvar fast ända tills Ättestupa glidit över
 * dem, och vilan finns inte. */
.hog { display: contents; }
/* Kantoskärpan finns bara på mobil - se mobildelen under Korthögen. */
.dikt__kant { display: none; }
.slut__vila { display: none; }

/* På mobil fyller korten skärmen, och målningen som drogs upp över sista
 * kortet såg ut att äta upp det. Här är det tvärtom: högen slutar vid sista
 * kortet och glider upp och bort, och målningen ligger still under och
 * blottas. Sedan rullar målningen vidare upp med mörkret under, som förut.
 *
 * Så går det till:
 * - Högen är en egen låda. Korten fastnar bara inom den, så när lådan tar
 *   slut följer hela högen med uppåt. Den ligger över Ättestupa (z-index).
 * - Ättestupa dras upp en skärmhöjd, in under sista kortet.
 * - Scenen är två skärmar hög: målningen, som fastnar i överkanten, och vilan.
 *   Målningen står still medan man rullar genom vilan - det är den sträckan
 *   sista kortet glider bort på. Vilan är också snäppunkten.
 * Sidan blir inte längre av det: Ättestupa börjar en skärm tidigare och är
 * en skärm högre. */
@media (max-width: 700px) {
  .hog {
    display: block;
    position: relative;
    z-index: 1;
  }
  .slut {
    margin-top: -100dvh;
    scroll-snap-align: none;
    /* clip, inte hidden: hidden gör sektionen till en egen rullningsyta,
     * och då fastnar målningen mot den i stället för mot sidan. */
    overflow: clip;
  }
  .slut .slut__bild {
    position: sticky;
    top: 0;
  }
  .slut__vila {
    display: block;
    height: 100dvh;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
}

.slut__morker {
  position: relative;
  overflow: hidden;
  height: 100dvh;
  display: grid;
  place-items: center;
  padding: 0 1.5rem;
  /* Ingen snappunkt här. Den hade kunnat rycka till sidan i det ögonblick
   * snäppningen slås på igen på väg upp mot dikterna. */
}

/* Ordet är skrivet i blod - en bild med vit botten bortnycklad. Det står
 * redan där när man rullar ner i mörkret, utan intoning. Blodet som droppar
 * från det ritas av js/blod.js. */
.slut__ord {
  position: relative;
  z-index: 1;
  margin: 0;
  width: min(82vw, 46rem);
  line-height: 0;
}

/* Blodduken under ordet. multiply släcker rött mot svart, så här ritas den
 * rakt av. Ordet står redan där, så blodet behöver inte vänta på det - bara
 * ett ögonblick, så att dropparna börjar rinna efter att man kommit ner i
 * mörkret och inte redan medan man rullar. */
.blod--morkt {
  mix-blend-mode: normal;
  /* Dropparna mörknar i takt med ordet ovanför. */
  filter: brightness(0.35);
  opacity: 0;
  transition: opacity 2.5s var(--rak);
}
.slut__morker.ar-synlig .blod--morkt {
  opacity: 1;
  transition-delay: 0.8s;
}

.slut__ord picture { display: block; }

.slut__ord img {
  display: block;
  width: 100%;
  height: auto;
  /* Mörkare, så att ordet sjunker in i mörkret i stället för att lysa. */
  filter: brightness(0.58);
}

/* --- Bläddring ----------------------------------------------------------- */

/* En vissen gren i högerkanten, med en knöl för varje stopp. En bloddroppe
 * hänger i knölen för den dikt som syns, och glider längs grenen när man
 * bläddrar. Grenen och droppen ritas av js/gren.js - grenens form följer hur
 * många stopp sidan har.
 *
 * Rörelsen här är mjuk med flit, till skillnad från resten av sidan som
 * klipper. Det är den enda delen man själv styr, och den ska kännas som att
 * bläddra i en bok, inte som att byta kanal. */
.prickar {
  --mjuk: cubic-bezier(0.45, 0.05, 0.2, 1);
  /* Barken. Torrt gråbrunt, som en gren som legat ute vintern över. */
  --bark-mork: #3b332d;
  --bark: #6f6358;
  --bark-ljus: #a39585;
  --bark-kontur: rgba(234, 231, 224, 0.55);
  position: fixed;
  z-index: 40;
  right: clamp(0.4rem, 1.6vw, 1rem);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  padding: 1.25rem 0;
}

/* Mot svart ljusnar barken och konturen blir mörk, annars försvinner grenen. */
.ar-morkt .prickar,
.vid-dikterna .prickar {
  --bark-mork: #5a4f46;
  --bark: #8e8174;
  --bark-ljus: #c2b4a4;
  --bark-kontur: rgba(2, 4, 6, 0.7);
}

.gren {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 44px;
  margin-left: -22px;
  overflow: visible;
  pointer-events: none;
  /* En tunn kontur, så att grenen syns även över ett fotografi som är lika
   * mörkt som barken. drop-shadow följer formen, även de små kvistarna. */
  filter: drop-shadow(0 0 0.6px var(--bark-kontur));
}
.gren__stam,
.gren__kvist { fill: url(#gren-yta); }
.gren__knol { fill: var(--bark-mork); }
.gren__ljus {
  fill: none;
  stroke: var(--bark-ljus);
  stroke-width: 0.5;
  stroke-linecap: round;
  opacity: 0.7;
}
/* Gradientens färger sätts här och inte i SVG:n, så att de kan bytas mot
 * svart med variablerna ovan. */
.gren stop.ett { stop-color: var(--bark-mork); }
.gren stop.tva { stop-color: var(--bark); }
.gren stop.tre { stop-color: var(--bark-ljus); }

/* Knappen syns inte själv - knölen i grenen är det man ser. Den är mycket
 * större än knölen, så att den går att träffa med ett finger. */
.prickar button {
  position: relative;
  z-index: 1;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}
/* Under pekaren tänds en tunn ring kring knölen. */
.prickar button::before {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  border: 1px solid var(--bark);
  opacity: 0;
  transform: scale(0.6);
  transition: transform 0.8s var(--mjuk), opacity 0.8s var(--mjuk);
}
.prickar button:hover::before {
  opacity: 0.6;
  transform: scale(1);
}
.prickar button[aria-current='true']::before { opacity: 0; }
.prickar button:focus-visible {
  outline: 1px solid var(--blod);
  outline-offset: 1px;
}

/* Droppen. Ytterdelen glider längs grenen. Innerdelen hänger i knölen och
 * gungar svagt med spetsen som fästpunkt - två rörelser som annars hade
 * skrivit över varandras transform. */
.prickar__droppe {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 50%;
  width: 22px;
  height: 22px;
  margin-left: -11px;
  pointer-events: none;
  transition: transform 1.2s var(--mjuk);
}
/* Vid sidans start ska droppen hänga på sin plats, inte glida dit uppifrån. */
.prickar__droppe.utan-glid { transition: none; }

.prickar__droppe svg {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 13px;
  height: 18px;
  /* Spetsen fästs strax ovanför knölens mitt, resten hänger under. */
  margin: -3px 0 0 -6.5px;
  overflow: visible;
  transform-origin: 50% 0;
  animation: hanga 5s ease-in-out infinite;
}

/* Tyngden drar den en aning nedåt och den smalnar av, sedan tillbaka. */
@keyframes hanga {
  0%, 100% { transform: scale(1, 1); }
  50%      { transform: scale(0.97, 1.05); }
}

/* Mot svart syns ingen skugga på pappret, men en svag glöd i blodet håller
 * droppen synlig. */
.ar-morkt .prickar__droppe .droppe__skugga,
.vid-dikterna .prickar__droppe .droppe__skugga { display: none; }
.ar-morkt .prickar__droppe svg,
.vid-dikterna .prickar__droppe svg { filter: drop-shadow(0 0 2.5px rgba(168, 56, 61, 0.35)); }

/* --- Fot ----------------------------------------------------------------- */

/* Samma uppbyggnad och typografi som foten på tornq.com/yoga: ordmärke och
 * en större rad överst, kolumner med små spärrade rubriker, en nedre rad.
 * Inter i tunn stil, samma storlekar och avstånd. Yoga-sidans visningssnitt
 * TT Commons är licensierat och faller där tillbaka på Inter - så även här.
 *
 * Helt svart, och utan korn: se .vid-foten längre ned. */
.fot {
  /* Positionerad, annars ritas korthögen - som ligger fast bakom - över foten. */
  position: relative;
  --fot-text: rgba(234, 231, 224, 0.7);
  --fot-blek: rgba(234, 231, 224, 0.4);
  --fot-linje: rgba(234, 231, 224, 0.14);
  --fot-snitt: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: #000;
  color: var(--fot-text);
  padding: clamp(3.5rem, 8vw, 6rem) clamp(1.25rem, 5vw, 5rem) clamp(1.75rem, 3vw, 2.5rem);
  font: 300 0.8125rem/1.85 var(--fot-snitt);
  letter-spacing: 0.004em;
}

.fot p { margin: 0; }

.fot__topp {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2rem;
  flex-wrap: wrap;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

/* Ordmärket: versaler med vid spärrning, andra raden mindre och blekare. */
.fot__marke {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 0;
  border: 0;
  background: none;
  color: var(--papper);
  font: 400 1.05rem/1 var(--fot-snitt);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  cursor: pointer;
}
.fot__marke-b {
  margin-top: 0.55rem;
  font-size: 0.8rem;
  letter-spacing: 0.42em;
  opacity: 0.55;
}

.fot__rad {
  /* Samma antikva som rubrikerna och namnet på startsidan. Snittet har låga
   * gemener och ser mindre ut än Inter i samma grad, så graden är större. */
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-size: clamp(1.45rem, 2.9vw, 2.05rem);
  font-weight: 500;
  line-height: 1.2;
  color: rgba(234, 231, 224, 0.66);
}

.fot__kolumner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 2.5rem 2rem;
  border-top: 1px solid var(--fot-linje);
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
}

.fot__rubrik {
  margin: 0 0 0.9rem;
  /* Samma antikva som namnet på startsidan. Den är tunnare än Inter och
   * behöver både större grad och lite ljusare färg för att hålla mot svart -
   * i Inter-storleken 0.625rem blir den hårstrån. */
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(234, 231, 224, 0.58);
}

.fot__nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.45rem;
}

/* Knappar som ser ut som länkar - de gör saker på sidan, som att öppna
 * gästboken, och är därför knappar. Som på yoga-sidan blir de ljusa under
 * pekaren. */
.fot__lank {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-align: left;
  /* Mejllänken är en riktig länk och skulle annars få en understrykning
   * som ingen annan länk i foten har. */
  text-decoration: none;
  /* En lång adress ska kunna brytas i en smal kolumn. */
  overflow-wrap: anywhere;
  cursor: pointer;
  transition: color 0.3s cubic-bezier(0.22, 0.61, 0.36, 1),
              border-color 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* En länk mitt i löptext syns inte som länk utan en linje under. Samma
 * hårfina linje som yoga-sidan använder för sina länkar i text. */
.fot__lank--i-text { border-bottom: 1px solid rgba(234, 231, 224, 0.25); }

.fot__lank:hover,
.fot__lank:focus-visible,
.fot__marke:hover,
.fot__marke:focus-visible {
  color: var(--papper);
}
.fot__lank--i-text:hover,
.fot__lank--i-text:focus-visible { border-color: var(--papper); }
.fot__lank:focus-visible,
.fot__marke:focus-visible {
  outline: 1px solid rgba(234, 231, 224, 0.5);
  outline-offset: 3px;
}

.fot__slut {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: clamp(3rem, 6vw, 4.5rem);
  border-top: 1px solid var(--fot-linje);
  padding-top: 1.75rem;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--fot-blek);
}

/* Kornet blandas med multiply och syns därför aldrig mot helt svart. Men över
 * fotens ljusa text blir det ett brus - så det tonas bort när foten är framme.
 * Klassen sätts av js/app.js. Foten lyfts inte över kornet i stället, eftersom
 * den då skulle täcka tråden i högerkanten. */
.korn { transition: opacity 0.6s var(--rak); }
.vid-foten .korn { opacity: 0; }

@media (max-width: 700px) {
  /* Luft till höger, så att texten inte hamnar under tråden i kanten. */
  .fot { padding-right: 2.75rem; }
}
/* --- Gästbok ------------------------------------------------------------- */

/* Pratbubblan nere till höger, med antalet kommentarer i ett litet märke -
 * som man känner igen från Instagram. På en dikt vänder den diktkortet
 * (se Diktkortet ovan). På start- och slutsidan öppnar den gästboken.
 *
 * Bubblan ligger på en ljus rund botten, så att den syns över både papper
 * och mörka bilder. Medan kortet är vänt eller panelen öppen är den fylld. */
.bubbla {
  position: fixed;
  z-index: 45;
  right: clamp(0.75rem, 3.5vw, 2.25rem);
  bottom: calc(clamp(1.25rem, 4vh, 2rem) + 1.6rem + env(safe-area-inset-bottom, 0px));
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(234, 231, 224, 0.94);
  color: var(--blod);
  box-shadow: 0 2px 8px rgba(22, 19, 15, 0.22), 0 0 0 1px rgba(22, 19, 15, 0.06);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.35s var(--rak), background-color 0.35s var(--rak),
              color 0.35s var(--rak), opacity 0.4s var(--rak);
}
.bubbla:hover,
.bubbla:focus-visible { transform: translateY(-2px) scale(1.05); }
.bubbla:focus-visible {
  outline: 2px solid var(--blod);
  outline-offset: 3px;
}

.bubbla__ikon {
  width: 1.6rem;
  height: 1.6rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linejoin: round;
}

.bubbla__antal {
  position: absolute;
  top: -0.25rem;
  right: -0.25rem;
  min-width: 1.4rem;
  height: 1.4rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--blod);
  color: var(--papper);
  box-shadow: 0 0 0 2px var(--papper);
  font: 600 0.72rem/1.4rem Inter, system-ui, sans-serif;
  text-align: center;
}
.bubbla__antal.ar-hopp { animation: antal-hopp 0.5s var(--rak); }
@keyframes antal-hopp {
  40% { transform: scale(1.35); }
}

.bubbla[aria-expanded="true"] {
  background: var(--blod);
  color: var(--papper);
}
.bubbla[aria-expanded="true"] .bubbla__ikon { fill: currentColor; }
.bubbla[aria-expanded="true"] .bubbla__antal {
  background: var(--papper);
  color: var(--blod);
  box-shadow: 0 0 0 2px var(--blod);
}

/* Mot svart: mörk botten och en tunn blodröd kant. */
.ar-morkt .bubbla {
  background: rgba(2, 4, 6, 0.75);
  color: var(--blod-ljus);
  box-shadow: 0 0 0 1px rgba(168, 56, 61, 0.45), 0 3px 10px rgba(0, 0, 0, 0.6);
}
.ar-morkt .bubbla__antal { box-shadow: 0 0 0 2px var(--natt); }

/* Bubblan syns bara på dikterna - på start- och slutsidan finns inget att
 * kommentera. visibility tar den ur tabbordningen när den tonats bort; den
 * slås av först när uttoningen är klar, men på direkt när den tänds igen. */
.bubbla.ar-dold {
  opacity: 0;
  transform: scale(0.85);
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.4s var(--rak), transform 0.4s var(--rak), visibility 0s linear 0.4s;
}

/* På diktkortet. js/gastbok.js flyttar bubblan in i kortet som syns, och där
 * sitter den över kortets nedre högra hörn, som ett märke. Den lyfts en bit
 * framåt, så att kortet inte skär igenom den när det lutar eller vänds. */
.dikt__lutning > .bubbla {
  position: absolute;
  right: -1.1rem;
  bottom: -1.1rem;
  transform: translateZ(40px);
}
.dikt__lutning > .bubbla:hover,
.dikt__lutning > .bubbla:focus-visible {
  transform: translateZ(40px) translateY(-2px) scale(1.05);
}

/* Foten har en egen länk till gästboken. */
.vid-foten .bubbla {
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 700px) {
  .bubbla {
    right: 0.6rem;
    width: 3rem;
    height: 3rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bubbla,
  .bubbla__antal {
    transition: none !important;
    animation: none !important;
  }
}

.gastbok-skugga {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(22, 19, 15, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--rak);
}
.gastbok-oppen .gastbok-skugga {
  opacity: 1;
  pointer-events: auto;
}

/* Panelen. visibility i stället för display: none, så att den kan glida -
 * och så att dolda fält varken kan få fokus eller läsas upp. Fördröjningen
 * på visibility låter den glida ut innan den försvinner. */
.gastbok {
  position: fixed;
  z-index: 80;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(28rem, 100vw);
  display: flex;
  flex-direction: column;
  /* Panelen klipper inte: grenen längs kanten sticker ut över sidan bakom.
   * Det är lagret innanför, .gastbok__innehall, som rullar. */
  overflow: visible;
  background: var(--papper);
  box-shadow: -1.5rem 0 3rem rgba(22, 19, 15, 0.18);
  transform: translateX(105%);
  visibility: hidden;
  transition: transform 0.45s var(--rak), visibility 0s linear 0.45s;
}
.gastbok.ar-oppen {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.45s var(--rak), visibility 0s;
}

.gastbok__innehall {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Samma antikva som brevet, namnet på startsidan och fotens rubriker.
   * Den ser mindre ut än maskinskriften den ersätter, så graderna i
   * gästboken är satta större och spärrningen mindre. */
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-weight: 500;
}

/* Vänsterkanten: en vissen gren, ritad av js/gren.js. Samma torra bark som
 * grenen i bläddringen. Den ligger över panelens kant och sticker ut en bit
 * över sidan bakom. */
.kantgren {
  /* Mörkare än bläddringsgrenen: den här ligger både mot panelens papper och
   * mot den dämpade sidan bakom, och måste hålla mot båda. */
  --bark-mork: #2f2823;
  --bark: #5c5047;
  --bark-ljus: #968776;
  position: absolute;
  z-index: 2;
  top: 0;
  left: -22px;
  width: 48px;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  filter: drop-shadow(1px 2px 2.5px rgba(22, 19, 15, 0.38));
}
.kantgren__stam,
.kantgren__kvist { fill: url(#kantgren-yta); }
.kantgren__knol { fill: var(--bark-mork); }
.kantgren__ljus {
  fill: none;
  stroke: var(--bark-ljus);
  stroke-width: 0.6;
  stroke-linecap: round;
  opacity: 0.7;
}
.kantgren stop.ett { stop-color: var(--bark-mork); }
.kantgren stop.tva { stop-color: var(--bark); }
.kantgren stop.tre { stop-color: var(--bark-ljus); }

/* Droppen i kvisten gungar som den i bläddringen, med spetsen som fästpunkt. */
.kantgren__svaj {
  transform-box: fill-box;
  transform-origin: 50% 0;
  animation: hanga 5s ease-in-out infinite;
}

.gastbok__topp {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem 1.5rem;
  background: var(--papper);
  border-bottom: 1px solid var(--papper-djup);
}

.gastbok__rubrik {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blod);
}

.gastbok__stang {
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--black);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
.gastbok__stang:hover { color: var(--blod); }

.gastbok__form {
  position: relative;
  padding: 1.5rem;
  border-bottom: 1px solid var(--papper-djup);
}

.gastbok__form label {
  display: block;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--black-ljus);
}

.gastbok__form input,
.gastbok__form textarea {
  display: block;
  width: 100%;
  margin-top: 0.4rem;
  padding: 0.65rem 0.75rem;
  border: 1px solid var(--papper-djup);
  border-radius: 0;
  background: #f3f1ec;
  color: var(--black);
  font: 500 1.1rem/1.45 "Cormorant Garamond", Georgia, "Times New Roman", serif;
  letter-spacing: 0;
  text-transform: none;
  resize: vertical;
}
.gastbok__form input:focus-visible,
.gastbok__form textarea:focus-visible {
  outline: 2px solid var(--blod);
  outline-offset: 1px;
}

.gastbok__form button {
  padding: 0.8rem 1.2rem;
  border: 0;
  background: var(--blod);
  color: var(--papper);
  font: 600 0.95rem/1 "Cormorant Garamond", Georgia, "Times New Roman", serif;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
}
.gastbok__form button:hover { background: var(--blod-djup); }
.gastbok__form button[disabled] {
  opacity: 0.45;
  cursor: default;
}

/* Fällan för robotar. Flyttad utanför bild i stället för display: none -
 * en del robotar hoppar över fält som är dolda på det sättet. */
.gastbok__falla {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.gastbok__besked {
  min-height: 1.2em;
  margin: 0.9rem 0 0;
  font-size: 1rem;
  font-style: italic;
  color: var(--black-ljus);
}
.gastbok__besked.ar-fel { color: var(--blod); }

.gastbok__lista {
  margin: 0;
  padding: 0.25rem 1.5rem 3rem;
  list-style: none;
}
.gastbok__lista li {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--papper-djup);
}
.gastbok__lista li.ar-ny { animation: trada-fram 0.6s var(--rak); }

.gastbok__namn {
  margin: 0 0 0.1rem;
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}

.gastbok__tid {
  display: block;
  margin-bottom: 0.45rem;
  font-size: 0.85rem;
  font-style: italic;
  letter-spacing: 0.02em;
  color: var(--black-ljus);
}

/* Radbrytningar i hälsningen behålls. Långa ord utan mellanslag bryts, så
 * att ingen kan skjuta panelen ur led med en enda lång rad. */
.gastbok__text {
  margin: 0;
  font-size: 1.15rem;
  line-height: 1.5;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.gastbok__lista li.gastbok__tomt {
  border-bottom: 0;
  font-size: 1.05rem;
  font-style: italic;
  color: var(--black-ljus);
}

/* --- Mindre skärmar ------------------------------------------------------ */

@media (max-width: 700px) {
  /* Smal nog att tråden i högerkanten inte skär genom titelns sista a. */
  .start__titel { width: 86vw; margin-top: -4%; }
}

/* --- Lugn rörelse -------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .dikt__bild,
  .start__hjarta,
  .start__titel img,
  .start__namn span { animation: none; }
  .dikt picture,
  .start__hjarta,
  .start__titel img,
  .start__namn span { opacity: 1; }
  * { transition-duration: 0.01ms !important; }
  /* Regeln ovan ger varje element en övergång på alla egenskaper - även den
   * synlighet som panelens innehåll ärver. Innehållet blir då synligt först
   * när en egen övergång hunnit klart, och en webbläsare som ritar få
   * bildrutor kan lämna det dolt fast panelen syns. Inuti panelen ska
   * synligheten följa panelen direkt. */
  .gastbok * { transition: none !important; }
  .prickar__droppe svg { animation: none; }
  .kantgren__svaj { animation: none; }
}
