/* THE KENAR BLOCK — the interior's maker, under the food carousel.
   Built 2026-08-10. The reasoning that decided the design is in tools/kenar.py;
   what follows is only how it is drawn. Two things are load bearing:

   HE IS NOT CUT OUT, HE IS MERGED. The portrait's background is nearly black
   (sampled 5 to 16) and his shirt is 14, so nothing can separate them. Instead the
   band is walnut and the picture's own edges are masked away, so the join
   disappears and he reads as cut out. The mask is soft on three sides and softest
   at the bottom, where the furniture card overlaps him.

   THE TOOLS ARE MASKS, NOT PICTURES. ut-yxa and ut-motorsag carry their drawing in
   the alpha channel over a flat black colour stream, so they are painted here as a
   cream fill masked by the file. Their own alpha does the tonal work: the steel
   head lands near full cream, the wooden handle at about a third of it. Dropped in
   as <img> on this band they would be black on brown.

   They are the CROPPED derivatives, not the delivered files. Each source holds two
   cut-outs with a gap between them, so `contain` fitted the whole frame into the
   box and most of the box was the gap: only a splinter of an object landed inside
   it, and the axe read as a stray shape rather than as an axe. tools/beskar_verktyg.py
   cuts each source down to its main object. What makes an axe an axe is the head. */

.kenar {
  /* MATCHAT MOT KAROSELLEN, Dennis 2026-08-11: samma struktur, bara speglad.
     Uppmätt vid 1440 låg matkarusellen på 697 text / 48 mellanrum / 439 bild och
     Kenar på 352 / 64 / 768. Bildkolumnen var alltså 87 px för smal och
     mellanrummet 16 för brett, vilket är varför speglingen inte läste som samma
     block vänt.

     27,5rem är 440 px, karusellens 439 plus en. Talet är MÄTT och inte delat:
     karusellens bredd räknas ur kortstorlek, fjäderstegen och lyftet, och de
     variablerna betyder ingenting för ett block utan kortlek. Ändras kortleken
     glider de isär -- säg till, så byter jag till en gemensam token i stället. */
  --han-b: min(27.5rem, 62vw);
  --mobel-b: min(17rem, 52vw);
  overflow: clip;          /* the tools reach past the column on purpose */
}

/* SPALTEN ÄR VÄGGEN, och den håller på riktigt. Dennis 2026-08-11: matkarusellen
   har osynliga väggar, håll dig till dem. left: 0 på verktygen räckte inte --
   isolerat i pixlar målade de från x=114 med väggen på 128, alltså 14 px förbi.
   Det är ROTATIONENS hörn: ett 208x215-block vridet 8 grader får en axelriktad
   låda som växer 27,8 px, hälften på var sida.

   Att kompensera med left: 14px hade varit rätt tal och fel lösning: det är
   räknat ur storlek OCH vinkel, så det tysta felet kommer tillbaka så fort någon
   ändrar endera. Klippet håller väggen oavsett vad som ställs innanför den.

   overflow-x: clip och inget mer: clip är det enda överflödsvärdet som låter den
   andra axeln stanna på visible. hidden hade gjort den till auto och kapat
   scenens avsiktliga överhäng nedåt, där möbelkortet hänger. */
.kenar .inre { overflow-x: clip; }

.kenar__rutnat {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);   /* karusellens eget mellanrum, inte ett eget */
  align-items: center;
  /* minmax(0, 1fr) rather than 1fr: the scene is positioned and its children
     stick out, and an auto track would size itself on that overhang and push the
     whole grid wider than .inre. The same trap the carousel's grid carries a note
     about. */
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 58rem) {
  /* SPEGLAT 2026-08-11 på Dennis begäran: illustrationerna till vänster, texten
     till höger. Ovanför ligger matkarusellen med orden till vänster, så de två
     banden växlar sida i stället för att upprepa samma uppställning.

     Kolumnerna byter plats med grid-column, ALDRIG med källordningen. Rubriken
     namnger scenen genom aria-labelledby och måste komma före den för den som
     läser linjärt eller med formatmallar av. Under 58rem faller allt till en
     kolumn och då är DOM-ordningen den enda ordningen -- rubrik först, som sig
     bör. */
  /* SCENKOLUMNEN ÄR BREDARE ÄN SCENEN, och det är vad som gör överhänget möjligt
     utan att röra väggen. `auto` gav kolumnen exakt scenens bredd, så scenens
     vänsterkant LÅG PÅ .inre:s vänsterkant -- uppmätt luft: 0 px -- och varje
     kort som hängde utanför scenen hamnade utanför den klippande förfadern på en
     gång. Det var inte de nya lägenas fel: samma mätning vid den gamla lutningen
     visade 33 % av ett kort kapat, tyst, i en grind som bara letade efter
     sidledsscroll.

     Luften är räknad ur det som faktiskt ska rymmas: nedersta kortet står
     --pol-ut + 2 x --pol-lut-v = 15 % utanför scenen, alltså 66 px av 440, och
     rotationen lägger till ett hörn på ~8. 5rem täcker det med marginal och
     kostar textkolumnen 160 av sina 696 px vid 1440. Under 58rem gäller inte
     regeln alls -- där är rutnätet en kolumn och korten har sin egen brytpunkt. */
  .kenar__rutnat {
    --scen-luft: 5rem;
    grid-template-columns:
      minmax(0, calc(var(--han-b) + 2 * var(--scen-luft))) minmax(0, 1fr);
  }
  .kenar__ord  { grid-column: 2; grid-row: 1; }
  /* Spänner båda raderna: knappraden (row 2) finns bara i textkolumnen, och utan
     spannet räknar rutnätet den som en HELT NY rad ovanpå scenens egen höjd --
     uppmätt +147px vid 1440 (568 -> 715) för ett block som inte skulle ändra
     storlek. Med spannet ryms knappen inom höjd scenen redan sätter (568px
     tillbaka), precis som innan knappen flyttades ut. */
  .kenar__scen { grid-column: 1; grid-row: 1 / span 2; }
  /* Knappen bor i markupen som en egen tredje rutnätscell, efter scenen, så att
     mobilen (en kolumn, DOM-ordning) får den under bilderna utan mediefråga.
     Här läggs den tillbaka i sin gamla plats: textkolumnens andra rad, precis
     under lead-stycket i .kenar__ord. */
  .kenar__cta { grid-column: 2; grid-row: 2; }

  /* ÖVERHÄNGET FÅR ALDRIG BLI STÖRRE ÄN MARGINALEN SOM FINNS. Verktygen hängde
     med ett fast -6rem, vilket är sant bara när sidan är bredare än .inre plus
     två gånger överhänget. Uppmätt före speglingen: yxan låg utanför högerkanten
     på hela spannet 1100 till 1320 px. Speglingen flyttade felet till sågen och
     vänsterkanten (upp till 86 px kapat, 940 till 1400) -- den skapade det inte,
     den bytte sida på det.

     Så överhänget räknas ur den fria marginalen i stället för att gissas:
     (100vw - 76rem) / 2, klämt till som mest 6rem. Under 76rem finns ingen
     marginal och då blir utsteget noll, alltså ligger verktyget kant i kant med
     scenen i stället för utanför skärmen. 76 och inte 74 (.inre:s bredd) för att
     100vw räknar in rullisten i vissa lägen, och två rem är billigare än ett
     kapat verktyg. */
  /* VERKTYGEN HÅLLER VÄGGEN. Dennis 2026-08-11: matkarusellen har osynliga
     väggar och det här bandet ska hålla samma. Uppmätt vid 1440: .inre går från
     128 till 1312 i båda banden, karusellens överskott KLIPPS av scenen och syns
     inte, medan sågen låg 110 px förbi vänsterväggen och syntes.

     Ett räknat utsteg löste bara halva saken -- det höll verktyget innanför
     SKÄRMEN, inte innanför spalten. Noll är svaret på den fråga han faktiskt
     ställde. Yxan behövde inget: den hänger åt höger, in i mellanrummet mellan
     scen och text, alltså innanför väggen hela tiden.

     .kenar framför väljaren, och det är inte kosmetika: regeln som sätter
     left: -6rem står LÄNGRE NER i filen, och vid samma specificitet vinner den
     senare. En mediefråga lägger inte till specificitet. */
  .kenar .kenar__verktyg--sag { left: 0; }
  /* De sista tio pixlarna. Porträttet fyller scenlådan kant i kant medan
     karusellens främsta kort ligger 11 px indraget från sin -- lådorna var lika
     breda, innehållet inte. Indraget bara till höger, så vänsterväggen står
     kvar orörd. */
  .kenar .kenar__scen { padding-right: 10px; }

  /* TEXTEN FYLLER INTE SIN KOLUMN, den slutar vid väggen och börjar där måttet
     tar slut. Dennis ritade streck på två skärmbilder för att visa vad han menade
     med spacing, och de mätte något jag inte hade mätt: avståndet från textens
     FAKTISKA slut till bilden, inte mellan kolumnkanterna.

     I matkarusellen börjar texten vid vänsterväggen och slutar 89 px före sin
     kolumn, eftersom måttet är 608 px i en kolumn på 697. Kvar blir 148 px luft
     innan polaroiderna. Jag hade speglat kolumnen men inte måttet, så Kenars text
     fyllde sina 696 och luften krympte till 59.

     Speglat på riktigt: samma 608 px mått, förankrat i HÖGER vägg med auto-margin
     till vänster. Texten slutar på 1312 som förut och börjar på 704, vilket ger
     147 px mot karusellens 148. */
  .kenar .kenar__ord { max-width: 38rem; margin-left: auto; }
  /* Yxan hängde -4rem utanför scenen, vilket var oskyldigt när scenen var 352 px
     bred och satt till höger. Efter speglingen och breddningen till 440 nådde
     dess bläck 633 medan textkolumnen börjar på 616 -- alltså 17 px IN i texten,
     mätt genom att dölja hela scenen och jämföra bildrutorna. Indragen så att
     bildsidans yttersta bläck landar på samma luft som matkarusellens. */
  .kenar .kenar__verktyg--yxa { right: 2.1rem; }
}

/* Texten går ända ut till väggen, Dennis 2026-08-11: textblocket ska sluta i
   samma kant som polaroiderna gör i Ur köket, och där är det polaroiderna som
   når spaltens ytterkant. I det speglade blocket är texten det yttersta, så
   34rem lämnade den 152 px innanför.

   JAG TRODDE DET SKULLE KOSTA RADLÄNGD OCH DET GJORDE DET INTE. Spalten är 696
   px mot sajtens läsbredd på 608, så jag skrev först att raderna blev längre än
   resten av sidan håller. Sedan räknade jag: 63 tecken per rad här och 63 i
   matkarusellen. Ingressen står i en större grad än karusellens brödtext, så den
   bredare spalten ger samma mått. Gissningen var fel och siffran är mätt.

   Kapet står kvar under 58rem, där kolumnen är hela sidan och 34rem är det enda
   som håller raderna läsbara. */
.kenar__ord .lead { max-width: 34rem; }
/* Källan för mellanrummet ovanför knappen, ärvt hit när style="margin-top"
   flyttade ur markupen -- se mobilens override strax ovan i filen. */
.kenar__cta { margin-top: var(--s-6); }
@media (min-width: 58rem) { .kenar__ord .lead { max-width: none; } }

/* The scene. A stage the three pieces are placed on, tall enough to hold the
   portrait plus the part of the furniture card that hangs below it. */
.kenar__scen {
  position: relative;
  width: var(--han-b);
  max-width: 100%;
  justify-self: center;
  padding-bottom: 5.5rem;      /* the furniture card's overhang */
}

/* --- him ---------------------------------------------------------------- */

.kenar__han { position: relative; margin: 0; width: 100%; display: flex;
              flex-direction: column; }

.kenar__han img {
  display: block;
  width: 100%;
  height: auto;
  /* The join, and the whole reason no cutting was needed. Soft on the sides and
     the top, hardest at the bottom edge where the card covers it anyway. Two
     gradients multiplied rather than a radial, so his head keeps its full
     strength while the frame's corners go: a radial dims the middle of the
     picture, which is his face.

     The top fade is 26 % and not 14 %, because the wall ABOVE his head is the lit
     part of the room -- sampled at a median of 77 against the band's own 28 -- so a
     short fade left a grey rectangle hanging over him. The number is the wall's
     brightness, not a taste. */
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0, #000 26%, #000 86%, transparent 100%),
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to bottom, transparent 0, #000 26%, #000 86%, transparent 100%),
    linear-gradient(to right, transparent 0, #000 15%, #000 85%, transparent 100%);
          mask-composite: intersect;
}

/* His name, set as a credit rather than as a caption: it is one line under a
   portrait on a dark ground, so cream at 14.6:1 and nothing else. */
/* ABOVE the picture, not under it. Under it the furniture card covered all but
   80 px of the line, which is how a credit turns into a smudge. Above, it reads as
   a title over a portrait and nothing can overlap it. */
.kenar__namn {
  display: block;
  order: -1;
  margin: 0 0 var(--s-2);
  font-family: var(--f-display);
  font-size: var(--t-xs);
  letter-spacing: var(--spar-vid);
  text-transform: uppercase;
  color: var(--papper);
}

/* --- the furniture ------------------------------------------------------ */

/* A photograph on paper, overlapping him at the bottom right. It is the evidence
   under the claim: the sentence says the benches are cut by hand, and this is the
   benches. */
.kenar__mobler {
  position: absolute;
  /* INÅT, INTE UTÅT. Kortet hängde -1.5rem utanför scenlådan och åt upp
     mellanrummet till texten: uppmätt 22 px luft mot matkarusellens 73, alltså
     drygt tre gånger tätare fast rutnätets gap var identiskt i båda. Lådan och
     bläcket är inte samma sak -- karusellens scenlåda är 25 px BREDARE än sitt
     främsta kort, Kenars kort låg 26 px utanför sin. Samma gap, motsatt tecken.
     +1.5rem flyttar kortet 48 px vänsterut och landar luften på karusellens. */
  right: 2.9rem;
  bottom: 0;
  width: var(--mobel-b);
  margin: 0;
  padding: 0.55rem 0.55rem 0.4rem;
  background: var(--papper);
  box-shadow: 0 14px 30px rgb(0 0 0 / 0.45);
  transform: rotate(-1.6deg);
}

/* A ROTATED BOX IS WIDER THAN ITS LAYOUT BOX by height times sin(angle), and this
   one hangs off the right edge as well. Both are paid for by .kenar's overflow:
   clip plus the scene's own width, and the sweep is what proves it -- see the
   note in the measurement script. */
.kenar__mobler img { display: block; width: 100%; height: auto; }

.kenar__mobler--ensam {
  position: static;
  right: auto;
  width: 100%;
  transform: none;
}

.kenar__bildtext {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--f-bok);
  font-size: var(--t-xs);
  line-height: 1.3;
  color: var(--valnot);        /* on the paper card, 13.9:1, not on the band */
}

/* --- the tools ---------------------------------------------------------- */

/* Cream painted through the file's own alpha. Both are ornament: they sit behind
   the portrait, they reach outside the column, and neither is allowed to take a
   pointer event or a screen reader's attention. */
.kenar__verktyg {
  position: absolute;
  display: block;
  background: var(--papper);
  opacity: 0.5;
  pointer-events: none;
  z-index: 0;
}

.kenar__han, .kenar__mobler { z-index: 1; }

.kenar__verktyg--sag {
  top: -3rem;
  left: -6rem;
  width: 13rem;
  aspect-ratio: 1048 / 1083;
  -webkit-mask: url("img/ut-motorsag-kropp-1024.webp") no-repeat center / contain;
          mask: url("img/ut-motorsag-kropp-1024.webp") no-repeat center / contain;
  transform: rotate(-8deg);
}

/* THE AXE HAS TO BE RECOGNISABLE AS AN AXE. At right:-8rem only a splinter of the
   handle reached into the frame and it read as a stray shape. The head is what
   makes an axe an axe -- the same lesson as the tongs that read as chopsticks --
   so it is pulled in far enough for the head to sit inside the picture, and moved
   up out of the furniture card's corner. */
.kenar__verktyg--yxa {
  right: -4rem;
  top: 30%;
  width: 12rem;
  aspect-ratio: 1334 / 1220;
  -webkit-mask: url("img/ut-yxa-huvud-1024.webp") no-repeat center / contain;
          mask: url("img/ut-yxa-huvud-1024.webp") no-repeat center / contain;
  transform: rotate(9deg);
}

/* A phone has no room for ornament that reaches outside the column: pulled in,
   shrunk, and dimmed further so they stay behind the words rather than competing
   with them. The furniture card stops overlapping him and simply follows, because
   an overlap on a 375 px column is two pictures fighting for the same 260 px. */
@media (max-width: 57.999rem) {
  /* KORTARE PÅ MOBIL, Dennis 2026-08-19: "flytta upp läs om moldau knappen lite
     mer och korta ner vertikalen på blocket på mobile". Tre tal gav bort höjd
     utan att bära något: sektionens padding var .band:s generella 4rem (ärvt,
     aldrig skrivet om för det här blocket -- matkarusellen ovanför skrev redan
     om sitt till clamp(2.5rem, 5vw, 4rem)), rutnätets gap var karusellens eget
     mått i ett block utan karusellens bildhöjd, och knappen fick dessutom ett
     eget margin-top ovanpå det gapet. Alla tre skalar ner här; ingen av dem rör
     desktop, som fortfarande faller under 58rem-frågorna nedanför. */
  .kenar { padding-block: clamp(2.25rem, 6vw, 4rem); }
  .kenar__rutnat { gap: 1.25rem; }
  .kenar__cta { margin-top: 0; }

  /* THE ORNAMENT MAY BLEED OFF THE PICTURE, NEVER OFF THE SECTION. Measured at
     375: the saw ran 24 px past the section's left edge and the axe 16 px past its
     right, and the gate was right to fail the 16 px of overflow that caused.

     Clipping the scene was the first fix and it was worse: the scene then became
     the reporting container itself, and declaring it an intentional crop would have
     exempted everything inside it -- the portrait, the card, the caption -- from
     clip checking for good. A future change could then cut a caption in half with
     the gate silent. So the tools are pulled in instead.

     The room available is exact: the scene is 307 px inside a 375 px section, so it
     is centred with 34 px to spare on each side and an ornament may hang 1.5rem off
     the picture and still be 10 px clear of the band. No exemption, no lost
     coverage, and on a phone this dims to 0.34 anyway. */
  .kenar__scen { padding-bottom: 0; width: min(20rem, 82vw); }
  .kenar__mobler {
    position: static;
    width: 100%;
    margin-top: var(--s-5);
    transform: rotate(-1deg);
  }
  .kenar__verktyg { opacity: 0.34; }
  /* Samma regel i det lilla. Ett fast -1.5rem kapade sågen med 5 px och yxan
     med 4 på 320, och bröt spalten på alla bredder. Noll håller båda. */
  .kenar__verktyg--sag { width: 9rem; left: 0; top: -1.25rem; }
  .kenar__verktyg--yxa { width: 8.5rem; right: 0; bottom: auto; top: 54%; }
}

/* Nothing here moves, so there is no motion to switch off -- but the tools are
   decoration at half strength over a photograph, and a visitor who has asked for
   less is served by less noise too. */
@media (prefers-reduced-motion: reduce) {
  .kenar__verktyg { opacity: 0.28; }
  .kenar__mobler { transform: none; }
}

/* ==========================================================================
   TRE RIKTNINGAR. Dennis, 2026-08-10: blocket ska se riktigt najs ut, han ska
   sticka ut mer, och det får inte bara vara staplade bilder.

   Variants are classes on .kenar, so the markup stays tools/kenar.py in every
   case and no copy can drift between them. Each answers the same question in a
   different way -- WHY does he stand out -- rather than nudging one layout three
   times:

     A Figuren        by SCALE. He is the tallest thing in the block and stands on
                      its floor, at nearly twice the size he has now.
     B Ljuskäglan     by LIGHT. One warm pool falls on him and everything else
                      sits at the dim edge of it.
     C Utställningen  by STATUS. He is framed and labelled the way a museum
                      credits a maker, in the site's own print vocabulary.

   What none of them touch: he is never cut out (the shirt measures 14 against a
   wall at 5 to 16, so nothing separates them), the tools stay cream masks painted
   through their own alpha, and the button still goes to historien.html.
   ========================================================================== */

/* --- A. FIGUREN --------------------------------------------------------- */

/* Scale, and a floor to stand on. The portrait grows to 30rem and the band's
   bottom padding goes, so he is cut off by the edge of the block rather than
   floating in the middle of it -- a figure standing in the frame instead of a
   photograph placed in it. The text column is capped so it cannot compete for
   width, and the tools grow with him and drop to a third of their strength: at
   this size they are structure behind a figure, not objects on a table. */
.kenar--figur { --han-b: min(30rem, 46vw); padding-bottom: 0; }
.kenar--figur .kenar__rutnat { align-items: end; }
.kenar--figur .kenar__ord { max-width: 27rem; padding-bottom: clamp(2.5rem, 5vw, 4rem); }
.kenar--figur .kenar__scen { padding-bottom: 0; align-self: end; }
.kenar--figur .kenar__han img {
  /* No bottom fade: the band's own edge is the cut now, and fading him out above
     it would leave him hovering. */
  -webkit-mask-image:
    linear-gradient(to bottom, transparent 0, #000 22%, #000 100%),
    linear-gradient(to right, transparent 0, #000 16%, #000 78%, transparent 100%);
          mask-image:
    linear-gradient(to bottom, transparent 0, #000 22%, #000 100%),
    linear-gradient(to right, transparent 0, #000 16%, #000 78%, transparent 100%);
}
.kenar--figur .kenar__namn { font-size: var(--t-sm); }
.kenar--figur .kenar__verktyg { opacity: 0.32; }
.kenar--figur .kenar__verktyg--sag { width: 17rem; left: -8rem; top: 4%; }
.kenar--figur .kenar__verktyg--yxa { width: 15rem; right: -6rem; top: 46%; }
/* One small card low on his left, so the furniture is evidence in the corner of
   the picture rather than a second photograph competing with him. */
.kenar--figur .kenar__mobler {
  right: auto;
  left: -4.5rem;
  bottom: 2rem;
  width: min(13rem, 42vw);
  transform: rotate(2deg);
}

/* --- B. LJUSKÄGLAN ------------------------------------------------------ */

/* Light. One warm pool behind him, and the rest of the block sits at its dim
   edge. The pool is two gradients rather than one: a wide ochre wash that lifts
   the whole area off the walnut, and a tighter pine-coloured core behind his head
   and shoulders. Gold is ornament here and never type -- it is a light on a
   photograph, and the text stays cream on the band at 14.6:1 well outside it.

   His picture is graded, not filtered into something else: contrast 1.06 and
   brightness 1.04, which is the difference between a print made lighter and a
   photograph pretending to be a different photograph. */
.kenar--ljus .kenar__scen { isolation: isolate; }
.kenar--ljus .kenar__scen::before {
  content: "";
  position: absolute;
  inset: -18% -30% -12%;
  z-index: 0;
  background:
    radial-gradient(58% 46% at 50% 34%, rgb(122 74 34 / 0.55), transparent 70%),
    radial-gradient(78% 64% at 50% 40%, rgb(201 162 39 / 0.16), transparent 72%);
  pointer-events: none;
}
.kenar--ljus .kenar__han { z-index: 2; }
.kenar--ljus .kenar__han img { filter: contrast(1.06) brightness(1.04); }
.kenar--ljus .kenar__namn { color: var(--guld-ljus); }   /* 10.26:1 on walnut */
/* Everything that is not him is at the edge of the light. */
.kenar--ljus .kenar__verktyg { opacity: 0.24; }
.kenar--ljus .kenar__verktyg--sag { left: -7rem; top: -1rem; }
.kenar--ljus .kenar__verktyg--yxa { right: -6rem; top: 24%; }
.kenar--ljus .kenar__mobler {
  filter: brightness(0.82) saturate(0.9);
  box-shadow: 0 10px 26px rgb(0 0 0 / 0.55);
  z-index: 2;
}

/* --- C. UTSTÄLLNINGEN --------------------------------------------------- */

/* Status. He is framed and captioned the way a museum credits a maker: a gold
   hairline around the picture, and a paper label under it carrying his name, his
   three tools in words, and the furniture as a small plate at the end of the
   line. That last part is the reason this is not a stack -- the second photograph
   becomes part of the label rather than another picture in the column.

   The frame means the portrait cannot fade at its edges, so the join with the
   band is gone and the picture is honestly a rectangle. That is the trade: this
   is the only one of the three where he is not cut out even by illusion, and it
   buys the most deliberate composition. */
.kenar--utstallning { --han-b: min(24rem, 58vw); }
.kenar--utstallning .kenar__han {
  padding: 0.5rem;
  border: 1px solid rgb(201 162 39 / 0.55);
  background: rgb(0 0 0 / 0.25);
}
.kenar--utstallning .kenar__han img {
  -webkit-mask-image: none;
          mask-image: none;
}
.kenar--utstallning .kenar__namn {
  order: 0;                      /* back under the picture, as a label reads */
  margin: var(--s-3) 0 0;
  font-size: var(--t-sm);
  color: var(--guld-ljus);
}
.kenar--utstallning .kenar__namn::after {
  content: "Yxa · Motorsåg · Hammare";
  display: block;
  margin-top: 0.35rem;
  font-family: var(--f-bok);
  font-size: var(--t-xs);
  letter-spacing: 0;
  text-transform: none;
  color: var(--tidning);
}
/* THE FURNITURE JOINS THE LABEL, IT DOES NOT QUEUE UNDER IT. First attempt put
   it full width below the frame, which is two framed pictures stacked -- exactly
   what Dennis said he did not want. Mounted small at the label's right it is one
   object: a portrait, its credit, and a plate showing the work, the way a museum
   wall label carries a detail photograph. */
.kenar--utstallning .kenar__scen { padding-bottom: 0; }
.kenar--utstallning .kenar__namn { text-align: left; padding-right: 8.5rem; }
.kenar--utstallning .kenar__mobler {
  right: 0.5rem;
  bottom: 0.5rem;
  width: 7.5rem;
  padding: 0.3rem;
  transform: none;
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.4);
}
/* The caption has no room at 7.5rem and the label already says what this is, but
   it is not deleted: hidden the standard way, so a screen reader still gets it and
   the picture is still a captioned picture rather than an undeclared one. */
.kenar--utstallning .kenar__bildtext {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.kenar--utstallning .kenar__verktyg { opacity: 0.2; }
.kenar--utstallning .kenar__verktyg--sag { width: 11rem; left: -5.5rem; top: -2rem; }
.kenar--utstallning .kenar__verktyg--yxa { width: 10rem; right: -5rem; top: 62%; }

/* ==========================================================================
   SCENEN OMBYGGD 2026-08-11 — Dennis: fronta designern

   Han ligger först och störst, fyra polaroider på möbler han ritat cirkulerar
   runt honom, och när sektionen kommer i bild fadas han in och verktygen flyger
   in under honom och ramar in honom.

   Reglerna står SIST i filen med flit. De äldre scenreglerna längre upp hör till
   den gamla kompositionen och till korten i Claude Design, och vid samma
   specificitet vinner den senare -- samma kaskadregel som lurade mig tidigare
   i dag, den här gången använd med avsikt i stället för emot mig.
   ========================================================================== */

.kenar__scen {
  position: relative;
  width: var(--han-b);
  max-width: 100%;
  /* 44/70, not 44/52. Dennis 2026-08-12: the tools go RIGHT UNDER him, and at
     52 there was nowhere under him to put them -- his cut-out filled 400 of the
     scene's 520 px, so the tool image had to start 170 px up inside him and the
     chainsaw bar ran straight across his folded forearms. Measured ink on ink,
     both alpha channels: 20 227 px of tool touching 20 227 px of him.

     Two ways out were measured before this one was picked. Shrinking him and the
     tools to fit the old scene works (52 % and 54 % gives 281 px of contact) but
     it pays for the room by making the man smaller, and he is what the block is
     about. Giving the scene the height instead keeps him at full size, 255 px
     wide, and lands on 223 px of contact -- the saw's tip grazing his lower edge,
     which is what "precis under honom" looks like when it is not a gap.

     Swept aspect-ratio x his bottom x tool width, 24 combinations at 1440.

     HÖJDEN ÄR EN VARIABEL NU, Dennis 2026-08-14: blocket ska bli kortare. Talet
     styr hela blockets höjd -- uppmätt vid 1440 var scenen 700 px mot textens
     300, alltså är det scenen och ingenting annat som sätter de 828 px blocket
     tog. Och 196 av de 700 låg UNDER honom, som plats åt verktygen; lyfter man
     dem behövs den platsen inte längre. Hans egen höjd följer scenens BREDD och
     påverkas inte, så --han-botten måste följa med ned när höjden krymper,
     annars trycks han ut genom överkanten. Svep de två ihop. */
  aspect-ratio: 44 / var(--scen-h, 70);
  padding: 0;
  justify-self: center;

  /* SCENEN SKJUTS NED, för dess låda omsluter inte sitt eget bläck. Namnet
     ligger på top: -15 % och polaroiderna på -1 %, alltså ovanför lådans
     överkant, medan botten är luft. align-items: center centrerar då LÅDAN och
     inte det man ser -- uppmätt låg bläcket 53 px ovanför innehållsytan och
     lämnade 27 px under, på varenda desktopbredd.

     Obalansen är konsekvent 80 px eftersom scenen är 440 px vid allt över 710.
     Halva den vore 9 %, men SÅ LÅNGT GÅR DET INTE, och det är en verklig konflikt
     mellan två av Dennis önskemål snarare än ett val:

     verktygen hänger på knappen (kenar.js) och står alltså STILLA när scenen
     flyttas -- så varje punkt scenen skjuts ned är en punkt verktygen klättrar i
     honom. Uppmätt: 0 % ger 49 % upp i honom, 9 % ger 59 %, och ansiktstaket går
     vid 55. Byggt och mätt per steg: 4 % -> grönt, 5 % -> grönt, 6 % -> 56 % och
     rött.

     5 % halverar obalansen (80 px -> 36, alltså -31 över och 5 under) och lämnar
     verktygen under taket. Vill man ha det helt centrerat måste antingen
     verktygen släppa knappen eller blocket bli högre igen.

     Alternativet vore padding-top på scenen, men den bär en aspect-ratio och då
     räknas höjden på innehållslådan i stället -- talet hade blivit lika fast och
     dessutom svårare att läsa. */
  translate: 0 var(--scen-skjut, 0%);
}

/* --- han ---------------------------------------------------------------- */

/* Ulrikas urklipp har äkta alfakanal, så han ligger fritt på valnöten utan mask,
   utan toning och utan den mjuka kant den gamla bilden behövde för att inte se
   ut som en ruta. Ett problem som löstes genom att välja rätt fil. */
.kenar__han {
  position: absolute;
  left: 50%;
  /* 28 %, which is where the tools' upper edge ends up once the scene is 70 tall.
     It is not a spacing choice: it is the value that puts his lower edge on their
     upper one. Variabel sedan 2026-08-14, av samma skäl som --scen-h: hans höjd i
     pixlar följer scenens BREDD, så en kortare scen gör honom till en större
     andel av den och skjuter ut honom genom överkanten om golvavståndet står
     kvar. De två talen svepes tillsammans. */
  bottom: calc(var(--han-botten, 28) * 1%);
  /* VARIABEL SEDAN 2026-08-17, av exakt samma skäl som --scen-h och --han-botten:
     Dennis bad om att göra honom mindre, och hans bredd var det enda talet i
     kompositionen som satt hårdkodat. Ett svep som måste skriva om en regel per
     kandidat sveper i praktiken aldrig -- se svep_kenar.mjs. */
  width: var(--han-andel, 58%);
  margin: 0;
  transform: translateX(-50%);
  z-index: 3;
}
.kenar__han img { display: block; width: 100%; height: auto; }

/* NAMNET STÅR KVAR ÖVER HONOM. Jag skrev först in en nollställning här för att
   flytta ner det, med en kommentar om att en äldre regel positionerade det fel --
   och den regeln var varken fel eller absolut. Den sätter order: -1 med avsikt,
   och motiveringen står kvar längre upp i filen: under porträttet blev namnet
   överlappat. I den nya kompositionen ligger verktygen där, så under vore ännu
   sämre. Kvar blir bara färgen, som byts mot guld nu när bandet bär honom fritt
   i stället för mot en mask. */
/* HIS NAME IS SIGNED, NOT SET. Dennis 2026-08-13. The block is about a man who
   cut the room by hand, and a spaced-out uppercase credit says the opposite of
   that. Caveat is already in the build -- it is what the polaroid captions are
   written in -- so this costs no font and puts his name in the same hand as the
   pictures around him. Uppercase, tracking and the small display size all have
   to be undone explicitly, because they come from the base rule further up.

   VIKT 400, INTE 700, Dennis 2026-08-13: "samma font som på menysidan där det står
   'Du som bara ska smaka'". Uppmätt på den raden (.hunger__replik, meny.html):
   Caveat, 30 px, VIKT 400, färg rgb(232 200 106) -- alltså redan samma familj och
   samma färg som här. Det enda som skilde var vikten, och det räckte för att läsa
   som en annan handstil: Caveat 700 är en tuschpenna, 400 är en reservoarpenna.
   Caveat ligger hostad som variabel font med spannet 400 700
   (src/assets/fonts.css), så 400 är en riktig vikt och ingen syntetisk uttunning.

   Storleken är kvar. Han bad om fonten, och namnet är en rubrik över ett porträtt
   medan menyraden är löpande text -- 40 px mot 30 vid 1440. Ett kommando tillbaka
   om han vill ha samma grad också. */
/* HÖGT UPP OCH FRITT, Dennis 2026-08-14. Namnet har flyttat tre gånger den här
   dagen och landade här efter en fråga i stället för en gissning till.

   Vägen dit, för den förklarar varför reglerna nedan ser ut som de gör. Först låg
   namnet som ett figcaption ÖVER porträttet i flödet. Dennis bad om att få det
   BAKOM personen, "för han fadeas ut i botten" -- vilket inte stämde: uppmätt är
   hans alfa 250-254 hela vägen ned, han är opak överallt, och det som ser ut som
   en uttoning är att LUMINANSEN faller till 3 av 255. Ett namn bakom honom
   nedtill hade försvunnit, inte skymtat. Så det lades där han är smalast, uppe
   vid hjässan, med en fjärdedel dolt. Sedan "högre upp", och sedan "mycket
   högre" -- och då är man förbi den punkt där något alls är dolt.

   På frågan om vad det skulle förhålla sig till där uppe svarade han FRITT
   OVANFÖR HONOM. Alltså är bakom-greppet övergivet med avsikt, och namnet står
   nu i luften mellan de övre polaroiderna.

   -15 % av hans bild sätter glyfernas mitt 78 px ned i blocket, mot hans hjässa
   på 118 och scenens överkant på 64. Svept: -12 % nuddar honom på telefon, -18 %
   och uppåt börjar tränga in i blockets egen toppmarginal. 100 % av glyferna
   står fria och ingen polaroid ligger under raden vid någon bredd.

   Det ligger kvar på z-index -1 inuti hans figur. Det syns inte längre -- inget
   överlappar -- men det kostar ingenting och håller stapeln sann om någon
   flyttar tillbaka namnet ned över honom. */
.kenar__namn {
  position: absolute;
  top: -15%;
  left: 50%;
  translate: -50% 0;
  width: max-content;
  max-width: 132%;          /* så det sticker ut förbi honom, men inte ur scenen */
  z-index: -1;              /* bakom bilden, inuti hans egen stapel */
  color: var(--guld-ljus);
  text-align: center;
  font-family: var(--f-hand);
  font-size: clamp(1.6rem, 1.1rem + 1.7vw, 2.5rem);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1;
  margin: 0;
}

/* It writes itself: a clip that opens left to right, at about the pace a hand
   moves. It has to sit on an inline-block -- clip-path on an inline box clips
   per line fragment, and the reveal jumps. The end state is the default and the
   start state only applies while the block has not been seen, so a browser that
   never runs the script gets the name whole. */
.kenar__namn span {
  display: inline-block;
  clip-path: inset(-0.35em 0 -0.2em 0);
  transition: clip-path 1100ms cubic-bezier(0.62, 0.02, 0.38, 1);
}
.kenar[data-kenar]:not([data-syns]) .kenar__namn span {
  clip-path: inset(-0.35em 100% -0.2em 0);
}
.kenar[data-syns] .kenar__namn span { transition-delay: 320ms; }

/* --- möblerna omkring --------------------------------------------------- */

/* Fyra lägen, handskrivna. En krets räknad med nth-child hamnar på en cirkel och
   läser som ett diagram; det här ska läsa som fyra kort någon lagt ut. */
.kenar__pol {
  position: absolute;
  width: 30%;
  margin: 0;
  padding: 0.4rem 0.4rem 0.35rem;
  background: var(--papper);
  box-shadow: 0 10px 24px rgb(0 0 0 / 0.42);
  z-index: 1;
}
.kenar__pol img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }

/* DE FYRA LÄGENA ÄR RÄKNADE MOT HANS ALFAKANAL, inte satta på känsla. Dennis
   2026-08-12: han ska ligga först av alla bilder, ingenting får täcka honom
   utom yxan och motorsågen. De gamla lägena gjorde precis det -- de två nedre
   låg 94 respektive 54 rastrerade punkter INNE i hans silhuett, alltså tvärs
   över hans korsade armar, och att han låg över dem i z-ordningen hjälpte inte:
   en ljus polaroidkant som skär genom hans arm syns lika mycket åt andra hållet.

   Vad mätningen av urklippet (u-kenar-fri, 1024x1612, äkta alfa) säger:

     * översta 30 % av honom -- huvud och hals -- är bara 35 % breda, så där
       finns 42 % ledig scenbredd till vänster och 36 % till höger.
     * från 35 % och ned fyller axlar och armar 81-99 % av hans egen låda. Där
       finns ingen lucka bredvid honom att lägga något i.

   Alltså: de två övre står bredvid huvudet, de två nedre är skjutna 6 % UTANFÖR
   scenens kant och ända ned -- det enda läget där en polaroid på 25 % går fri
   från armarna. Sökt igenom 20 x 40 lägen per sida vid sex bredder; smalare än
   25 % behövdes inte. Rotationerna ingår i mätningen, för en roterad ruta tar
   mer plats än en rak. */
/* SIX NOW, AND THEY RUN DOWN THE SIDES. Dennis 2026-08-13: use the sides rather
   than the top and the bottom, and let them touch each other a little. Four in
   the corners left the middle of each edge empty and the two lower ones sat on
   the floor beside the tools; three down each side fills the height he actually
   occupies and leaves the floor to the axe and the saw.

   THE COLUMN LEANS OUT AS IT GOES DOWN, and that is his shape rather than a
   design choice. Level with his head there is 40 % of the scene free on each
   side; level with his folded arms there is almost none. So the top card sits
   close to the edge and the two below it have to stand further out.

   MEASURE WHERE THE GATE MEASURES. The first sweep of this reported no contact
   at all at a position the gate then failed with 99 sample points, for two
   reasons that both come down to standing somewhere else: it never forced the
   images eager, and it read the positions on a fixed timeout rather than after
   the entrance had finished. Re-sweep with tools/sond_kenar.mjs and
   tools/svep_kenar.mjs, which both borrow the gate's own preparation.

   THE NUMBERS LIVE IN VARIABLES, and that is a bug fix rather than a tidy-up.
   The six positions used to be six hand-written pairs under a comment that
   closed eleven lines too early -- so the line after it, plain prose, parsed as
   a selector and swallowed the width declaration that followed it. The cards ran
   at 30 percent for a day while the file said 26, the sweep that chose the 25
   percent step was reasoning about a card size that never applied, and nothing
   went red because the gate measures collisions, not intentions. A comment can
   now only cost a comment: the step, the width and the lean are declared once on
   the scene, every card derives from them, and a card that is not the size the
   file claims is a contradiction the sweep prints.

   NEVER WRITE A COMMENT-CLOSING SEQUENCE INSIDE A COMMENT, not even quoted in
   backticks to talk about one. Writing this very paragraph closed the block
   early and swallowed the variables underneath it, which cost a full sweep
   before the computed styles showed --pol-b arriving empty. Say "closed early"
   in words. tools/kolla_kommentarer.py greps the whole tree for it now. */
/* TALEN ÄR ENHETSLÖSA med flit. Ett kort behöver dela sitt eget kantavstånd med
   sin egen bredd för att veta hur långt in mot mitten det ska starta, och CSS
   kan dela ett tal med ett tal men inte en procent med en procent. Så
   variablerna är rena tal och `* 1%` sätts på där de blir längder. */
.kenar__scen {
  /* Kortets bredd, andel av scenens bredd. Kortet är kvadratiskt plus padding,
     alltså är dess HÖJD i punkter av scenen ungefär --pol-b x (scenbredd /
     scenhöjd) -- och det är den höjden som avgör om grannarna lappar eller
     glappar. Vid 44/70 är en tredjedels bredd bara en femtedels höjd, vilket är
     precis den räkning som saknades när stegen valdes till 25 och kommentaren
     ändå påstod tre punkters överlapp. */
  --pol-b: 34;
  --pol-topp: -1;      /* översta kortets överkant */
  /* Kortet är 21,4 punkter högt här (34 % bredd på en 44/70-scen), så ett steg
     på 19 lappar grannarna med 2,4 punkter och ett på 25 -- det som stod här --
     lämnar 3,6 punkters GLAPP. Det var felet Dennis pekade på: filens egen
     kommentar påstod tre punkters överlapp medan mätningen visade luft. 16 ger
     5,4 punkter, vilket läser som en hög någon lagt ut utan att gömma ett foto.

     Att gå längre kostar höjd i stället: tre kort med steg 16 spänner 52 % av
     scenen mot hans 72, och ett mindre steg drar upp kolumnen från hans fötter.
     Det är avvägningen, och den är hans att flytta om han vill ha tätare. */
  --pol-steg: 16;
  --pol-ut: -3;        /* översta kortets indrag utanför scenkanten */

  /* KOLUMNERNA LUTAR OLIKA MYCKET, och det är inte en oregelbundenhet -- det är
     att de står i olika rum. Till vänster ligger .inre:s vägg direkt utanför
     scenkanten, den vägg Dennis bad om 2026-08-11 och som sågen redan kapades
     tillbaka till. Till höger ligger mellanrummet mot texten, 744 px vid 1440,
     där yxan alltid har fått hänga.

     Det syntes i mätningen innan det syntes i koden: vid en gemensam lutning på
     6 skar kort 4 hans arm med 27 punkter medan kort 3, dess spegelbild till
     vänster, gick fritt. Höger kolumn ligger tre punkter lägre -- det är vad
     --pol-forskjut gör -- och möter därför armarna där de är bredast. Att höja
     den gemensamma lutningen till 9 löste kort 4 och kapade i stället
     vänsterkolumnen mot väggen: kort 5 låg 66 % utanför .inre.

     Alltså två tal. Vänster stannar på 6, som är vad väggen har råd med.
     Höger går till 9, som är vad armen kräver. */
  --pol-lut-v: 6;
  --pol-lut-h: 9;
  --pol-forskjut: 3;   /* höger kolumn börjar lägre, så raderna inte står i takt */

  /* SCENENS HÖJD, och därmed hela blockets. Dennis 2026-08-14: kortare block,
     och verktygen ännu längre upp. Det visade sig vara SAMMA rörelse -- en
     kortare scen behåller hans pixelhöjd (den följer scenens bredd) men flyttar
     golvet uppåt, så verktygen stiger i honom utan att golvtalet rörs. Vid 70
     nådde de 14 % upp i honom, vid 64 når de 20 % med samma 6 %.

     64 och inte mindre, svept över fyra vyer:

       70  ->  blocket 828 px, verktygen 14 % upp, gott om luft
       64  ->  blocket 768 px, verktygen 20 % upp, han ryms med 24 px
       58  ->  blocket 708 px, MEN han trycks 3 px ut genom överkanten
               och en polaroid börjar skära honom
       52  ->  blocket 648 px, han 39 px ut, 62 punkter polaroid i honom

     Under 64 tar scenen alltså slut innan han gör det, och han är vad blocket
     handlar om. --han-botten skalas med höjden av samma skäl: 28 av 70 är 26 av
     64, och står talet kvar hamnar hans hjässa utanför.

     44 EFTER EN RUNDA TILL, Dennis 2026-08-14: "super korta ner blocket ifrån
     botten, ta bort massa onödig empty space". Det gick att ta 160 px till, och
     skälet är att SCENENS GOLV INTE BÄR NÅGOT LÄNGRE. Så länge verktygen stod på
     golvet behövdes höjden under honom till dem; sedan de hänger på knappen
     (kenar.js) är den ytan bara luft. Hans förankring följde med ned från 24 till
     6 % av samma skäl -- avståndet fanns till verktyg som inte är där.

     Uppmätt vid 1440: blocket 728 -> 568 px och tomrummet i botten 144 -> 63,
     alltså MINDRE än bandpaddingens 64. Allt internt tomrum är borta; det som
     står kvar är bandets egen luft, som delas av hela sidan.

     40 går inte: då trycks hans hjässa 10 px ut genom scenens överkant.

     Historiken, för den förklarar varför talen ser ut som de gör:
     64 stoppades av att verktygen klättrade i honom, inte av utrymmet -- och det
     gick att köpa loss genom att SÄNKA deras golv i samma steg. Scenen tappar
     fyra punkter, golvet fyra procent, och verktygen står kvar på 19 % upp mot
     20 innan. Blocket går 768 -> 728 px och det tomma i botten 94 -> 68.

     728 är dessutom rätt tal av ett annat skäl: matkarusellen direkt ovanför är
     725 px. De två banden är samma familj -- bild och text, speglade -- och att
     de nu väger lika mycket är hur de skulle ha stått hela tiden.

     De sista 64 av de 68 kvarvarande pixlarna är BANDPADDINGEN, och den delas av
     alla fem band på sidan (mätt: 64/64 på matkarusellen, hallen, Instagram och
     tacket). Att bryta den för ett block gör tomrummet till ett hopp i rytmen i
     stället. Rör den inte utan att flytta allihop. */
  --scen-h: 44;

  /* HAN ÄR MINDRE OCH STÅR HÖGRE, Dennis 2026-08-17: "kan vi göra jerzy lite
     mindre och få yxan och motorsågen sticka ut lite ifrån jerzy, den ska
     fortfarande ligga på han men just nu smälter den in en del".

     "SMÄLTER IN" ÄR MÄTBART, och det var det som gjorde ändringen möjlig att göra
     rätt: uppmätt låg 88,6 % av verktygens eget bläck PÅ hans silhuett. Ett verktyg
     vars kontur bara går mot hans mörka rock har ingen kant att läsas mot, alltså
     syntes knappt en åttondel av dem som föremål. Måttet heter verktygUte i
     matt_kenar.mjs och har verktygens bläck som nämnare -- inte hans silhuett, som
     täckningsmåttet. Samma överlapp kan vara mycket av en liten man och lite av
     stora verktyg, så de två går inte att räkna ur varandra.

     DE TVÅ TALEN HÖR IHOP OCH INGET AV DEM GÅR ATT VÄLJA FÖR SIG. Han är ankrad i
     BOTTEN medan verktygen hänger på knappens linje (kenar.js) och står still.
     Krymper han faller hjässan ned mot dem, och samma verktygslinje skär honom
     högre upp i en kortare kropp: ansiktstaket på 55 % nås omedelbart. Uppmätt vid
     1440 med golvet kvar på 6: 58 % ligger PÅ 55, 52 % ger 61, 46 % ger 69.
     Det finns alltså ingen marginal att låna -- det gamla läget stod exakt på
     taket. --han-botten lyfter hela figuren så att verktygen möter honom längre
     ned igen, och det kostar ingenting: scenens golv bär ingenting sedan verktygen
     släppte det 2026-08-14.

     SVEPT, 36 kandidater över hans bredd x verktygens bredd x hans golv, mätt vid
     1440 och 375 (tools/svep_kenar.mjs <url> han). Vad som binder åt varje håll:

       han  golv  ute     täcker  upp   polaroider
       58     6   11,4 %   8,6 %  55 %  0     gammalt läge, PÅ ansiktstaket
       58    14   18,5 %   7,9 %  46 %  66    han lyfts in i korten
       54    16   24,7 %   8,4 %  47 %  23    fortfarande in i korten
       50    16   28,3 %   9,4 %  51 %  0     VALT
       46    20   39,2 %   9,4 %  50 %  0     mer utstick, men -21 % på honom

     Att lyfta honom utan att krympa honom går INTE: vid 58 % är han så bred att
     han går in i polaroidkolumnerna redan vid golv 14 (66 träffar). Krympningen är
     alltså det som betalar för lyftet, inte bara ett önskemål vid sidan av det.
     Det är samma sorts koppling som --scen-h och --han-botten redan har.

     50 OCH INTE 46: Dennis skrev "lite mindre". 58 -> 50 är 255 -> 220 px, alltså
     14 % smalare, och tar utsticket från 11,4 till 28,3 % -- två och en halv gång
     mer synlig kontur. 46 ger 39 % men gör honom 21 % smalare, och han är vad
     blocket handlar om. Ett kommando bort om han vill mer.

     VERKTYGEN ÄR ORÖRDA. --verktyg-b står kvar på 70 %. Att bredda dem ger också
     mer utstick men lyfter deras överkant lika mycket (bilden behåller sin kvot),
     så vid 78 % mäter samma läge 61 % upp i honom -- över ansiktstaket. Dennis bad
     inte om större verktyg, han bad om att se dem. */
  --han-andel: 50%;
  --han-botten: 16;

  /* GÖMSTÄLLET FÖR ÖVERSTA RADEN FLYTTADE MED HONOM. 210 -> 165 %.
     Talet säger hur långt ett kort i rad 0 reser NED för att hamna mitt på hans
     bål innan entrén börjar. När han lyftes 10 punkter och krympte 8 ligger bålen
     högre och är kortare, så 210 % bar korten FÖRBI honom och ned på hans ben:
     uppmätt 52 % och 32 % dolda mot ett golv på 80. Två kort som poppar fram ur
     luften i stället för ur honom, och inget i det landade läget visar det.
     Svept (tools/svep_gomstalle.mjs): 150, 165 och 180 % ger alla 100 % dolt vid
     1440, 820 och 375; 195 % faller till 86/66 och 210 till 52/32. 165 är mitten
     av det som håller, inte kanten av det.
     Rad 2 och 3 rörs inte -- de mäter 90-100 % dolda som de står. */
  --ner-rad1: 165%;
  --scen-skjut: 5%;

  /* VERKTYGENS LYFT ÖVER SCENGOLVET. Dennis 2026-08-14: "flytta upp yxan och
     motorsågen mer". 6, upp från 2, och det är det steg som är märkbart högre
     utan att bryta hans EGET krav från den 12:e -- verktygen under honom, inte
     över armarna.

     Uppmätt vid 1440 (och 375 följer inom några tiondelar):

       2 %  ->  rör 1,72 % av hans silhuett, når  7,7 % upp   ligger löst på golvet
       6 %  ->       5,10 %                      14,0 %       möter hans uttonade fåll
       10 % ->       8,68 %                      20,2 %       sågen skär in i midjan
       14 % ->      14,88 %                      26,4 %       klart över honom

     Vid 6 % är kontakten hans nedersta sjundedel, alltså den utfasade fållen och
     inte kroppen. Vid 10 % ligger motorsågens hus över midjan, och det är samma
     fel som fanns 2026-08-12 fast mindre. Därför stannar det här. */
  /* 4. Vägen hit: 2 var det som höll läget när scenen kortades (den kortare
     scenen lyfter dem lika mycket som golvet sänkte dem, netto 19 % upp), och
     sedan bad Dennis 2026-08-14 om att flytta upp dem en tredje gång. 4 ger
     21,6 % upp i honom.

     6, OCH DÄRMED ÄR REGELN FRÅN DEN 12:e ÖVERGIVEN. Uppmätt och avläst i bild
     vid 1440:

       2 %  ->  19 %    yxbladet en bit under armarna
       4 %  ->  22 %    bladet precis under dem, skaftet vid armbågen
       6 %  ->  24 %    bladet ligger tvärs över de korsade underarmarna
       8 %  ->  27 %    sågens hus över bålen också

     Dennis fick 6 %-bilden bredvid 4 %-bilden och bad ändå om mer, fjärde gången
     samma dag. Det är hans beslut och det är taget med bilden framför sig, så
     "verktygen under honom, inte över armarna" gäller inte längre -- verktygen
     korsar armarna med avsikt nu.

     DET ÄNDRAR VAD GRINDEN SKA VAKTA. Ett tak som säger "under armarna" och som
     flyttas varje gång någon vill högre vaktar ingenting. Höjdkontrollen mäter
     därför inte längre armarna utan ANSIKTET, som är en gräns ingen har bett om
     att flytta -- se motiveringen i tools/matt_kenar.mjs.

     Golvet är 7 på telefonen; se brytpunkten längre ned.

     TALET GÖR INGENTING PÅ DESKTOP LÄNGRE, verifierat 2026-08-17. Läs kenar.js:
     den nollställer --verktyg-linje, mäter skillnaden mellan verktygens mitt och
     knappens, och skriver den skillnaden tillbaka. Alltså KOMPENSERAS varje värde
     på golvet bort -- verktygens läge över 58rem bestäms helt av knappen. Hittat
     genom en negativ kontroll som inte föll: golvet sattes till 70 % och grinden
     rapporterade noll problem, för verktygen stod kvar på exakt samma plats.

     Historiken ovanför -- de fyra lyften och deras uppmätta tal -- gällde alltså
     fram till commit 54d2740, då linjen infördes. Den står kvar för att den
     förklarar VARFÖR regeln om armarna övergavs, men leta inte efter ett lyft här
     i dag. Golvet styr fortfarande två riktiga fall: utan JavaScript (godkänt läge)
     och under 58rem, där knappen ligger ovanför scenen och skriptet tar bort
     linjen. Vill man flytta verktygen på desktop är det KNAPPEN som flyttas. */
  --verktyg-golv: 6%;
}

/* Varje kort säger bara VILKEN RAD och VILKEN SIDA det är. Allt annat -- läget,
   och startläget entrén kommer ifrån -- räknas ur det. Det är rotorsaksfixen
   till att kort 5 och 6 stod utan startläge: när fyra blev sex den 13:e fick de
   nya sina lägen men inte sina gömställen, eftersom gömställena var fyra
   handskrivna par. Nu kan ett sjunde kort inte glömmas bort -- det ärver. */
.kenar__pol--1 { --rad: 0; --sida:  1; rotate: -7deg; }
.kenar__pol--3 { --rad: 1; --sida:  1; rotate:  5deg; }
.kenar__pol--5 { --rad: 2; --sida:  1; rotate: -4deg; }
.kenar__pol--2 { --rad: 0; --sida: -1; rotate:  6deg; }
.kenar__pol--4 { --rad: 1; --sida: -1; rotate: -5deg; }
.kenar__pol--6 { --rad: 2; --sida: -1; rotate:  4deg; }

.kenar__pol {
  /* Kortets avstånd från SIN egen kant, negativt = utanför scenen. --pol-lut
     sätts av kolumnen nedan, så formeln är en och samma för alla sex. */
  --kant: calc(var(--pol-ut) - var(--rad) * var(--pol-lut));
  width: calc(var(--pol-b) * 1%);
  top: calc((var(--pol-topp) + var(--skift, 0) + var(--rad) * var(--pol-steg)) * 1%);
  bottom: auto;
}
.kenar__pol--1, .kenar__pol--3, .kenar__pol--5 {
  --pol-lut: var(--pol-lut-v);
  left: calc(var(--kant) * 1%); right: auto;
}
.kenar__pol--2, .kenar__pol--4, .kenar__pol--6 {
  --pol-lut: var(--pol-lut-h);
  right: calc(var(--kant) * 1%); left: auto;
  --skift: var(--pol-forskjut);
}

/* --- verktygen som flyger in -------------------------------------------- */

/* Ulrikas fil har yxan och sågen redan korsade, alltså är kompositionen hennes.
   Den gamla lösningen var två separata masker med varsin rotation och varsitt
   överhäng, som fick räknas om varje gång blocket flyttades. */
.kenar__verktyg-in {
  position: absolute;
  left: 50%;
  /* Up off the scene's floor, Dennis 2026-08-13. A share rather than a rem, so
     the lift is the same gesture on a phone: 14 px at 1440, 7 px at 375, and the
     two lower polaroids -- which sit at bottom: 1 % -- keep the scene's floor to
     themselves.

     2 % IS THE CEILING, NOT A PREFERENCE. Lifting them presses more of their
     alpha into his, and the gate allows 3 % of his silhouette. Swept at three
     widths, the contact runs 0 % lift -> 1.2 %, 2 % -> 2.5 %, 2.5 % -> 3.1 %,
     4 % -> 4.4 %, and 375 px binds because his cut-out fills more of the
     squarer scene there. So 2 % is the last step that clears it everywhere.
     Going further is a decision about the gate, not about the CSS: the contact
     sits 13 % up in him at 4 % lift against a 25 % ceiling, so it is his faded
     hem the tools touch, not his arms -- but that ceiling was set with room to
     spare and raising it should be argued, not slipped in. */
  /* Golvet plus den linjejustering kenar.js räknar fram. Positiv justering =
     högre upp. Utan JavaScript är --verktyg-linje osatt och golvet gäller
     ensamt, vilket är ett läge Dennis godkänt -- se skriptet för varför talet
     inte går att skriva i CSS. */
  /* HELA SCENEN, sedan 2026-08-17. Behållaren var en 70 %-bred låda som hängde på
     knappens linje, och båda verktygen låg i den på width 100 % -- det var det som
     höll dem korsade. Dennis flyttade dem isär ("motorsågen under högra sidan av
     polaroid bilden och yxan på vänster sida"), så lådan har ingen egen form kvar
     att bära. Den är bara koordinatsystemet nu: inset 0 gör varje procent nedan en
     procent av SCENEN, vilket är samma nämnare som polaroiderna räknas i.

     VAD SOM FÖLL BORT MED DEN, och det ska stå rakt ut: --verktyg-linje gäller inte
     längre. Dennis bad 2026-08-14 om att verktygen skulle ligga i linje med knappen,
     och kenar.js räknade fram den linjen genom att mäta LÅDANS mitt mot knappens.
     Två verktyg i två nedre hörn har ingen gemensam mitt att linjera, och de sitter
     dessutom långt under knappens höjd. Skriptet skriver fortfarande variabeln --
     den läses inte här längre. Backas det här läget kommer linjen tillbaka av sig
     själv; behålls det ska raden i kenar.js tas bort med en notis. */
  inset: 0;  z-index: 4;
}
/* The axe carries the box's height because it is in flow; the saw lies over it
   on top: ONE frame, so the two files land crossed the way Ulrika drew them.
   See tools/dela_verktyg.py -- both are written into the composite's own
   bounding box, which is what makes `inset: 0` enough here. */
/* VAR OCH ETT PÅ SIN EGEN PLATS. Talen är variabler av samma skäl som allt annat i
   den här scenen: de måste svepas, och en regel per kandidat sveps aldrig.
   Procenten räknas mot scenen (behållaren är inset 0), alltså samma nämnare som
   polaroidernas --kant och --pol-b. Därför går lägena att läsa mot korten:

     nedre VÄNSTRA kortet  ligger -15 % till  19 % i sidled, 35-69 % från botten
     nedre HÖGRA kortet    ligger  67 % till 121 % i sidled, samma höjd
       (ur --pol-ut -3, --pol-lut-v 6 / --pol-lut-h 9, --pol-b 34, --pol-steg 16)

   Yxan står alltså vid vänsterkortets underkant och sågen under högerkortets, som
   Dennis bad om. Att korten hänger utanför scenkanten är avsikten sedan 2026-08-13
   -- de ska sticka ut i mellanrummet -- så verktygen får göra det med dem. */
.kenar__vlager { position: absolute; display: block; }
.kenar__vlager img { display: block; width: 100%; height: auto; }

/* SPEGLADE OCH TRYCKTA INÅT, Dennis 2026-08-17: "kan vi spega yxan och motorsågen
   och pusha dom närmare jerzy".

   scale: -1 1 som EGEN property, inte inne i en transform: entrén sätter translate
   och rotate på samma element, och en transform här hade fått upprepa dem. Ordningen
   är translate -> rotate -> scale, så speglingen vänder också entréns lutning -- de
   faller in spegelvänt, vilket är följdriktigt och inte något att kompensera bort.

   SÅGENS DEKAL BLIR BAKVÄND, och det är kontrollerat innan speglingen gjordes:
   höljet bär "141 S". Uppmätt renderad storlek är dekalen 19 px bred på desktop och
   13 på telefon, alltså 3,8 respektive 2,7 px per tecken -- oläsligt åt BÅDA hållen,
   så speglingen kostar ingenting man kan se. Skulle blocket någon gång renderas
   större måste dekalen speglas tillbaka i filen (tools/tata_verktyg.py), för då är
   en bakvänd logotyp det första ögat hittar.

   ANDRA STEGET INÅT, Dennis 2026-08-17: "flytta in dom mycket längre in så dom
   nästa nuddar varandra". Yxan -6 -> 24 %, sågen -10 -> 22 %.

   OCH DET GICK INTE ATT GÖRA I SIDLED. Lådornas kanter ljuger om avståndet: båda
   verktygen ligger diagonalt i sina rutor, så rutorna kan överlappa medan bläcket
   står långt isär. Uppmätt bläck mot bläck vid 1440, med lådorna 41 punkter isär i
   sidled, var det verkliga avståndet 217 px. Sveptes de rakt inåt bottnade gapet på
   37 px och VÄXTE sedan igen -- de gled förbi varandra.

   Sonden fick därför skriva ut VAR de närmaste punkterna satt, och då syntes det:
   vid x 35 % låg sågens bom på 50 % höjd och yxans huvud på 40 %. Gapet var LODRÄTT
   hela tiden. Yxan skulle upp, inte in. (Första gissningen var motsatsen -- att
   sänka yxan till samma golv som sågen -- och den gjorde gapet större, 65 px.)

   Svept lodrätt: 16 % -> 44 px, 20 % -> 26, 21 % -> 9, 22 % -> 22, 24 % -> 1.
   Talen är inte monotona kring minimum eftersom det är två diagonaler som möts, så
   spannet är svept i hela punkter i stället för halverat. 21 valt: 9 px är en hårfin
   remsa band mellan dem, alltså "nästan nuddar" och inte "nuddar".

   TELEFONEN HAR EGET TAL. Scenen är kvadratiskare där, så samma andel ger ett annat
   möte: vid 21 % mäter mobilen 2 px, alltså kontakt. Se brytpunkten längre ned. */
.kenar__vlager--yxa {
  left: var(--yxa-v, 24%);
  bottom: var(--yxa-n, 21%);
  width: var(--yxa-b, 30%);
  scale: -1 1;
}
.kenar__vlager--sag {
  right: var(--sag-h, 22%);
  bottom: var(--sag-n, 10%);
  width: var(--sag-b, 44%);
  scale: -1 1;
}

/* --- entrén -------------------------------------------------------------

   Ordningen är Dennis, omlagd 2026-08-13: han står först, sedan POPPAR
   möblerna ut BAKIFRÅN honom, och när de landat faller verktygen ner. Den
   gamla ordningen var den omvända -- verktygen först, möblerna sist -- och
   berättade en annan sak. Den här berättar att allt i rummet kom ur honom, och
   att verktygen är det han gjorde det med.

   VARFÖR "BAKIFRÅN" ÄR GRATIS: han ligger på z-index 3 och polaroiderna på 1,
   så en polaroid som står på hans bröst ÄR dold, utan mask och utan clip. Det
   enda som behövs är ett startläge som ligger där. Talen nedan är uppmätta,
   inte satta: hans bredaste rad (armarna) är 252 px mot polaroidens 110 på
   desktop och 133 mot 74 på telefon, och varje translate flyttar just den
   polaroidens mitt dit. De skiljer sig åt per polaroid eftersom procenten är
   av elementets egen låda, och per brytpunkt eftersom lägena är egna där.

   Sluttillståndet står på elementen själva och startläget bara när blocket ÄNNU
   INTE syns. Utan JavaScript sätts data-syns aldrig, men då gäller inte heller
   startläget, så allt står färdigt och synligt. En entré får inte kunna gömma
   innehåll. */
.kenar[data-kenar]:not([data-syns]) .kenar__han,
.kenar[data-kenar]:not([data-syns]) .kenar__pol,
.kenar[data-kenar]:not([data-syns]) .kenar__vlager { opacity: 0; }

.kenar[data-kenar]:not([data-syns]) .kenar__han { transform: translateX(-50%) translateY(14px); }

/* THEY FALL FROM THE TOP OF THE BLOCK, one after the other. Dennis 2026-08-13.
   -260 % is of the LAYER's own height, and the layer is about 40 % of the
   scene's, so that is a good scene-height above where it lands: it starts out
   of the block and arrives at the floor rather than easing up from under it.

   The tilt is part of the fall, not decoration. Each one comes down turned the
   way it is going to swing -- the axe from the left, the saw from the right --
   and straightens as it lands, so the two read as separate objects dropped one
   after the other instead of one layer sliding in twice.

   translate and rotate rather than transform: the container owns transform for
   its own translateX(-50%), and a transform here would have to restate it. */
.kenar[data-kenar]:not([data-syns]) .kenar__vlager {
  translate: 0 -260%;
  rotate: -14deg;
}
.kenar[data-kenar]:not([data-syns]) .kenar__vlager--sag { rotate: 12deg; }

/* translate and scale as their OWN properties, not inside transform: .kenar__pol
   already carries its tilt in `rotate`, and a transform here would have to
   restate that tilt or animate it away by accident.

   ETT GÖMSTÄLLE, RÄKNAT, INTE SEX HANDSKRIVNA. Sidled: kortets mitt ligger vid
   --kant + --pol-b/2 räknat från sin egen kant, och ska till scenens mitt, 50.
   Skillnaden delas med kortets egen bredd eftersom translate räknar i procent av
   elementet, och --sida vänder tecknet för högerkolumnen. Han är bredast över de
   korsade armarna och ligger på z-index 3, så ett kort som står där ÄR dolt --
   utan mask, utan clip.

   Höjdled kan inte räknas på samma sätt: kortets höjd i scenens procent beror på
   scenens bildförhållande, som CSS inte känner till här. Den är därför ett tal
   per RAD -- tre, inte sex -- och de säger bara hur långt kortet ska flytta för
   att hamna mitt på honom: den översta raden står i höjd med hans huvud och
   måste ner till bålen, den mellersta ligger redan rätt, den nedersta en bit
   under. Grinden mäter påståendet i stället för att lita på talen. */
/* Talen är omräknade 2026-08-14 sedan grinden slutade mäta mot en utsträckt
   alfakarta -- se tools/matt_kenar.mjs. Rad 2 stod på -60 %, vilket lyfte kortet
   till hans HJÄSSA: där är han 24-36 % bred och kortets överkant stack upp i
   luften ovanför huvudet. Uppmätt täckning på telefon 61 %, och 54 % vid 320,
   mot ett golv på 80. Noll lägger kortet mitt på bålen i stället, som är 83-99 %
   bred, och det är hela idén med gömstället. */
/* TALEN ÄR SCENVARIABLER SEDAN 2026-08-17, av samma skäl som --han-andel blev en:
   de måste räknas om varje gång HAN flyttas eller byter storlek -- gömstället är
   hans kropp -- och ett tal som bara står i en regel går inte att svepa. Just det
   hände när han krympte till 50 % och lyftes: kort 1 och 2 startade 52 % och 32 %
   täckta mot ett golv på 80, alltså syntes de innan de flög in. Det är inget en
   skärmbild av det LANDADE läget kan visa. */
.kenar__pol--1, .kenar__pol--2 { --ner: var(--ner-rad1, 210%); }
.kenar__pol--3, .kenar__pol--4 { --ner: var(--ner-rad2,  60%); }
.kenar__pol--5, .kenar__pol--6 { --ner: var(--ner-rad3,   0%); }

.kenar[data-kenar]:not([data-syns]) .kenar__pol {
  scale: 0.42;
  translate: calc(var(--sida) * (50 - var(--kant) - var(--pol-b) / 2)
                  / var(--pol-b) * 100%)
             var(--ner);
}

.kenar__han,
.kenar__pol {
  transition: opacity 700ms ease, transform 700ms cubic-bezier(0.2, 0.9, 0.3, 1.05),
              translate 620ms cubic-bezier(0.2, 0.9, 0.3, 1.05),
              scale 620ms cubic-bezier(0.2, 0.9, 0.3, 1.05);
}

/* A fall, so the curve accelerates and overshoots a little at the end rather
   than easing symmetrically. The opacity is over almost at once: a tool that
   fades while it falls is a ghost, and these are supposed to be dropped. */
.kenar__vlager {
  transition: opacity 200ms ease,
              translate 780ms cubic-bezier(0.45, 0, 0.35, 1.16),
              rotate 780ms cubic-bezier(0.45, 0, 0.35, 1.16);
}

/* HE HAS TO BE OPAQUE BEFORE ANYTHING HIDES BEHIND HIM. The first pass started
   the polaroids at 300 ms, inside his own 700 ms fade, and the frames showed
   exactly what that means: at half opacity he is a window, and polaroid 1 was
   visible THROUGH his chest before it had moved anywhere. Hiding behind someone
   costs nothing in z-index and everything in timing. His fade is shortened to
   550 ms and the first polaroid starts after it, not during it. */
.kenar__han { transition-duration: 550ms; }

/* The fade is short and the journey is not. A polaroid that faded for the whole
   620 ms would arrive as a ghost; at 180 ms it is solid while it is still behind
   him, so what the eye sees is a thing coming out from behind him rather than a
   thing appearing next to him. */
.kenar[data-syns] .kenar__pol { transition-duration: 180ms, 700ms, 620ms, 620ms; }

/* Left, right, left, right, down the sides -- the order the eye would lay them
   out, not 1-2-3-4-5-6 down one side and then the other. 80 ms apart rather
   than 90, so six of them take about as long as four used to. */
.kenar[data-syns] .kenar__pol--1 { transition-delay: 560ms; }
.kenar[data-syns] .kenar__pol--2 { transition-delay: 640ms; }
.kenar[data-syns] .kenar__pol--3 { transition-delay: 720ms; }
.kenar[data-syns] .kenar__pol--4 { transition-delay: 800ms; }
.kenar[data-syns] .kenar__pol--5 { transition-delay: 880ms; }
.kenar[data-syns] .kenar__pol--6 { transition-delay: 960ms; }

/* After the last picture has landed (960 + 620), then the saw a beat behind the
   axe. 260 ms apart is close enough to read as one gesture in two parts and far
   enough that you see which one lands first. */
.kenar[data-syns] .kenar__vlager--yxa { transition-delay: 1620ms; }
.kenar[data-syns] .kenar__vlager--sag { transition-delay: 1880ms; }

@media (prefers-reduced-motion: reduce) {
  /* Skriptet sätter attributet direkt, så det här handlar bara om resan dit. */
  .kenar__han, .kenar__pol, .kenar__vlager,
  .kenar__namn span { transition: none; }
}

@media (max-width: 57.999rem) {
  /* 40/62, the same extra room the desktop scene got, in this scene's own
     proportion. Without it the phone kept the old problem in miniature: the saw
     stood 38 px up inside him against 20 px on desktop, because the scene here
     is squarer and his cut-out therefore fills even more of it. Measured after:
     the contact drops from 5806 px to under 300, and the two lower polaroids keep
     their own positions, which were swept separately for this breakpoint. */
  /* Egen höjd här, av samma skäl som lägena har egna tal: rutnätet är EN kolumn
     på telefon, så scenen och texten staplas i stället för att stå bredvid
     varandra. Blockets höjd är därför text PLUS scen, inte den högsta av dem,
     och att korta scenen ger punkt för punkt tillbaka i blocket. */
  .kenar__scen { aspect-ratio: 40 / var(--scen-h-mobil, 62); }

  /* EGNA LÄGEN PÅ SMAL SKÄRM, av två skäl som båda är uppmätta.

     Scenen är kvadratiskare här (40/46 mot 44/52) och polaroiden är bredare i
     andel -- 36 % av scenen mot 28 % på desktop, för de 0,4rem paddingen väger
     mer på en liten låda. Desktoplägena krockade därför med honom i hela det
     smala spannet: 26-32 rastrerade punkter i hans arm på 320-820 px.

     Och namnet: på en telefon står "JERZY KENAR" över 0,285-0,715 av scenens
     bredd mot 0,387-0,613 på desktop, alltså rakt i vägen för hörnen. De två
     övre står därför ovanför namnets rad i stället för bredvid den, och de två
     nedre vid axlarna med överhäng utanför scenen -- det enda som går fritt.
     Överhänget är 33 px vid 375 px skärm, mot 47 px marginal utanför scenen, så
     ingen sidledsscroll uppstår; grinden mäter det. Sökt igenom 36 x 124 lägen
     per hörn vid fem bredder. */
  /* -12%, not -8%. The taller scene moved the name up relative to this corner,
     and at 320 px the gate caught the collision the eye would not: 2 px of
     polaroid across "JERZY KENAR". The 2 px are the ROTATION, not the position --
     a -8 deg box 63 px wide reaches 71 px, so its right edge sat at 51 against
     the name's 49. Moving it out clears it at every width down to 320, and stays
     well inside polaroid 3's -16 %, which the sweep already proved scroll-free. */
  /* Three down each side here too, but pushed further out than on desktop: the
     scene is 40/62 rather than 44/52, so his cut-out fills much more of its
     width and the only free lane is outside the scene's own edge. The overhang
     is what the gate's sideways-scroll sweep watches.

     Only the variables change here -- the six positions derive from them exactly
     as on desktop. The step has to be its own number rather than the desktop
     one: the card is a wider share of a squarer scene, so the same step in
     points is a different gap in pixels. */
  /* Här är rutnätet EN kolumn och scenen står centrerad i .inre, alltså finns
     luft åt BÅDA håll och ingen vägg på ena sidan -- därför är kolumnerna lika
     mycket lutade här, till skillnad från på desktop. Utsticket är ändå det som
     binder: klippet sitter på .inre även här, och luften är bara några tiotal
     pixlar på en telefon. */
  .kenar__scen {
    /* 32, INTE 36, och det är namnet som sätter taket. Vid 320 px är scenen 198
       px bred och "Jerzy Kenar" i Caveat nästan lika brett som han -- ett kort på
       36 % skar signaturen med två kort, och det gick inte att flytta bort
       vertikalt: svept över topplägen från -16 till +6 satt krocken kvar i varje
       enda, för den är horisontell. 32 är den bredaste kort som går fritt, och
       det kostar inget överlapp: steget kompenserar. */
    --pol-b: 32;
    --pol-topp: -4;
    /* 22, upp från 13. Dennis 2026-08-17: "sprid ut bilderna mer".

       DET GICK INTE ATT GÖRA I SIDLED, och det är värt att stå kvar vid innan
       någon försöker igen. Klustret mäter 136,1 % av scenens bredd på BÅDA
       brytpunkterna -- korten ligger alltså redan lika brett utlagda som på
       desktop. Att skjuta dem längre ut kapas av .inre: svept vid 320 px, som är
       den vy som binder, ger lut 6 / ut -9 redan 10,3 % kapat kort mot taket 10,
       och lut 8 / ut -9 ger 22 %. Sidled är slut.

       MÅTTET ÄR HUR MYCKET AV VARJE KORT SOM SYNS, inte hur brett högen ligger.
       Räknat som andel av kortets yta som varken är skymd av ett kort ovanpå,
       dold bakom honom eller kapad av .inre. Nuläget mätte 53,3 % på telefonen och
       56,5 % på desktop -- alltså nästan samma ANDEL, vilket är varför en
       proportionsjämförelse säger att allt är i sin ordning.

       Det är i PIXLAR skillnaden sitter, och det är den Dennis ser: 56,5 % av ett
       160 px-kort är en 90 px remsa man kan läsa, 53,3 % av ett 82 px-kort är 44 px
       och läser som en trave. Telefonen behöver alltså ett EGET tal, inte desktops.

       Svept 13/16/19/20/21/22/24 vid 375, 320 och 820, alla med noll träffar i hans
       silhuett, noll krock med namnet och noll kapning:

         13  ->  53,3 %   nuläget
         19  ->  72,6 %
         22  ->  82,1 %   VALT
         24  ->  88,5 %   korten står nästan fria, högen slutar läsa som en hög

       22 och inte 24: de ska fortfarande lappa varandra som utlagda kort. Vid 24
       är överlappet nere i 6,7 punkter av ett 30,7 punkter högt kort och de sex
       står i praktiken på rad.

       KOSTAR INGEN HÖJD. Scenen bär aspect-ratio, så kolumnen växer inuti den:
       blocket mäter 755 px vid 375 både före och efter. Kort 5 och 6 slutar vid
       69 % av scenen mot verktygens överkant på 54, alltså samma möte som på
       desktop där korten slutar på 66 mot 51,5. */
    --pol-steg: 22;
    /* -9 och 4, svept över de fem telefonvyerna mot BÅDA villkoren samtidigt,
       som drar åt olika håll: mindre utstick trycker korten in i honom (vid -6
       och 3 låg 130 punkter i hans silhuett), större utstick trycker dem ut
       genom klippet (vid -15 kapades ett kort till 20 %). -9/4 är rent på alla
       fem, och stegen åt båda håll är också rena, så det ligger mitt i fönstret
       och inte på dess kant. */
    --pol-ut: -9;
    --pol-lut-v: 4;
    --pol-lut-h: 4;
    --pol-forskjut: 2;

    /* 59, ned från 62, och vinsten är mycket mindre än på desktop: 18 px mot 60.
       Skälet är att blocket här är text PLUS scen i en kolumn, och texten är
       335 px som inte går att korta. Scenen kan inte ge särskilt mycket heller:
       han fyller en kvadratiskare scen till större del, och vid 56 trycktes hans
       hjässa 1 px ut genom överkanten vid 320.

       Det bindande blev inte höjden utan hur högt verktygen hamnar i honom. En
       kortare scen lyfter dem utan att golvtalet rörs, och telefonen når taket
       långt före desktop: 58 landar på 21 %, precis på gränsen, och 57 och nedåt
       lägger yxbladet synligt över hans underarm. 59 håller dem på 20 %, samma
       som desktop, med en punkts marginal. De 5 px som 58 hade gett till är inte
       värda att stå på gränsen.

       60 EFTER EN VÄNDA TILL: 59 höll på telefonerna men 820 px -- den bredaste
       vyn som fortfarande går på den här brytpunktens enkolumnsläge -- landade
       exakt på 21. Svepet hade bara telefonbredder i sig, så den vyn syntes
       aldrig.

       58 SEDAN GOLVET BLEV EN VARIABEL PER BRYTPUNKT. Samma köp som på desktop:
       scenen tappar två punkter och verktygsgolvet sänks, så lyftet står kvar på
       19 % upp. Blocket 836 -> 825 px. Telefonen ger fortfarande mycket mindre
       än desktop, och det är inte scenens fel -- blocket är text PLUS scen i en
       kolumn, och brödtexten är 335 px.

       GOLVET ÄR 6 HÄR OCH 4 PÅ DESKTOP, och det är inte en slarvig avvikelse:
       scenen är kvadratiskare, han fyller mer av den, och samma tal ger inte
       samma läge. Tar man desktops 4 rakt av hamnar telefonen på 19,2 % och
       verktygen står synligt lägre än på skärmen bredvid.

       820 ÄR BRYTPUNKTENS VÄRSTA VY och den ska med i varje svep här: den
       sträcker sig upp till 928 px, och två gånger under det här arbetet har
       just den fällt ett tal som alla telefonbredder släppte igenom.

       7 följer desktops 6 -- se den kommentaren för varför regeln om armarna är
       övergiven. Talen skiljer sig för att scenen är kvadratiskare här. */
    --scen-h-mobil: 46;
    /* 18, upp från 12, när han krympte till 50 % 2026-08-17. Samma köp som på
       desktop och av samma skäl -- se den kommentaren. Uppmätt vid 375 med han på
       50 %: golv 16 ger 49 % upp och golv 20 ger 46 %, båda med noll
       polaroidträffar, alltså är telefonen INTE den vy som binder här. Det är
       ovanligt nog att vara värt en rad: varje tidigare tal i det här blocket har
       fällts av telefonen eller av 820. Anledningen är att han är smalare i px här
       och därför inte når polaroidkolumnerna när han lyfts. */
    --han-botten: 18;
    --verktyg-golv: 7%;

    /* VERKTYGEN ÄR LIKA STORA I FÖRHÅLLANDE TILL HONOM SOM PÅ DESKTOP, Dennis
       2026-08-17: "gör yxan och motorsågen proportionerliga som på desktop".

       DET VAR ETT MÄTBART FEL, inte en smaksak. Uppmätt vid 375 mot 1440: yxan var
       0,60 gånger hans bredd på telefonen mot 1,08 på skärmen, sågen 0,88 mot 1,20.
       Alltså inte "lite mindre" utan nästan hälften, och det är därför blocket
       läste som två små föremål vid en man i stället för hans verktyg över honom.

       TALEN ÄR RÄKNADE, INTE SVEPTA, och det går här därför att målet är känt: samma
       läge relativt HONOM som på desktop. Han är 50 % av scenen i båda brytpunkterna,
       så verktygens bredd i scenprocent kan gå rakt över -- 54 och 60. Höjdledsleden
       kan det inte: hans golv är 16 % av en 44/44-scen på desktop och 18 % av en
       40/46-scen här, alltså är samma avstånd under hans fötter olika många procent
       av scenhöjden. De räknas om via hans egen höjd: yxan står 6,1 % av hans höjd
       under fötterna på båda, vilket blir 11,2 % scenhöjd på desktop och 13,8 här.

       BEVISET ÄR ATT GRINDENS EGNA TAL SAMMANFALLER. Samma tre mått som taken i
       kenar_tak.mjs mäter, vid 375 efter ändringen mot 1440 som det står:

         täcker  17,5 %  mot  16,6 %
         upp     41,0 %  mot  41,2 %
         ute     57,5 %  mot  58,4 %

       Tre mått som möts på under en procentenhet är inte en gissning som råkade
       hålla -- det ÄR definitionen av proportionerlig, mätt i stället för sagd.
       Före ändringen mätte telefonen 11,8 / 26,1 / 36,0.

       Talen står också i data/verktygslage.json, som vinner om filen finns. De två
       ska hållas lika: filen är Dennis egna dragningar och den här raden är vad en
       färsk kopia av repot bygger. */
    --yxa-v: -0.4%;
    --yxa-n: 13.8%;
    --yxa-b: 54%;
    --sag-h: -0.3%;
    --sag-n: 13.2%;
    --sag-b: 60%;
  }

  /* Inga egna gömställen längre. De var fyra handskrivna par som räknade mot den
     här brytpunktens egna lägen, och de blev fel i samma ögonblick som lägena
     ändrades -- vilket är precis vad som hände: kort 5 och 6 fanns aldrig här.
     Sidleds räknas nu ur --kant och --pol-b, som ÄR brytpunktens egna, så
     formeln följer med av sig själv. Höjdledstalen per rad gäller båda
     brytpunkterna: scenen är kvadratiskare här men han fyller den i samma
     proportion, och grinden mäter att varje kort verkligen startar dolt. */
}
