/* THE INSTAGRAM BLOCK — a drawn phone with their own feed in it.
   Built 2026-08-10. Why it is drawn rather than photographed, and why the hashtag
   is theirs, is in tools/instagram.py. This file is only how it looks.

   Three directions live at the bottom as classes on .ig. Everything above them is
   shared, so the copy, the alt text and the link cannot differ between the three. */

.ig {
  /* Dennis 2026-08-18: "gör instagram blockets visuella lite mindre", mobil och
     desktop. Skalat 0,85x ur de gamla talen (17rem/52vw) snarare än gissat till
     ett runt tal, så telefonen krymper proportionerligt mot allt annat i
     blocket som redan var mätt mot den. */
  --tel-b: min(14.5rem, 45vw);        /* phone width */
  --skarm-r: 1.6rem;                  /* the screen's corner */
  /* The filmstrip's numbers live here because the bar's height is DERIVED from them
     further down. Written as two widths and one ratio rather than as heights, so the
     thumbnails keep their shape and the bar keeps following it. */
  --minia-b: 1.45rem;                 /* a thumbnail in the row */
  --minia-nu-b: 2.1rem;               /* the raised one */
  --minia-r: 9 / 13;                  /* their shape */
  --minia-nu-r: 9 / 15;               /* the raised one is taller too */
  --minia-nu-h: calc(var(--minia-nu-b) * 15 / 9);
}

.ig__rutnat {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  /* minmax(0, 1fr): the scene holds positioned children that reach outside it, and
     an auto track sizes itself on that overhang and pushes the grid past .inre. */
  grid-template-columns: minmax(0, 1fr);
}

/* TRE BARN SEDAN 2026-08-17, INTE TVÅ: orden, scenen och knappen. Dennis ville ha
   knappen UNDER telefonen på mobil, och en knapp som ligger inuti ordkolumnen kan
   aldrig hamna efter scenen -- `order` byter bara plats på syskon. Se markupen i
   tools/instagram.py för vad som prövades i stället.

   PÅ TELEFON GÖR REGELN INGENTING. Rutnätet är en kolumn och barnen faller i
   dokumentordning: orden, telefonen, knappen. Det är hela mobilfixen -- den syns
   inte i någon regel, för den ÄR frånvaron av en. */
@media (min-width: 58rem) {
  .ig__rutnat {
    grid-template-columns: minmax(0, 1fr) auto;
    /* Radavståndet nollas och knappens egen marginal bär avståndet till texten i
       stället. Med rutnätets gap kvar hade knappen ramlat 4rem ned från stycket den
       hör till, alltså sett ut att höra till nästa sak i stället. */
    row-gap: 0;
  }
  .ig__ord   { grid-area: 1 / 1; align-self: end; }
  .ig__knapp { grid-area: 2 / 1; align-self: start; margin-top: var(--s-6); }
  .ig__scen  { grid-area: 1 / 2 / 3 / 3; }

  /* VARFÖR `end` OCH `start` OCH INTE `center` PÅ BÅDA: scenen spänner två rader
     och är mycket högre än orden, så rutnätet delar ut överskottet LIKA mellan de
     två raderna. Med center i båda hamnar texten mitt i sin halva och knappen mitt
     i sin, alltså långt ifrån varandra med en tom remsa emellan.

     Med texten i botten av rad 1 och knappen i toppen av rad 2 möts de vid
     radgränsen -- och paret hamnar exakt mitt i scenen ändå. Räknat: gränsen ligger
     på text + slack/2, alltså är parets mitt slack/2 + (text + knapp)/2, vilket är
     samma tal som behållarens mitt. Ingen kompensation behövs, och den gäller vid
     varje texthöjd. */
}

.ig__ord .lead { max-width: 32rem; }

/* NO HYPHENATION IN THIS HEADING. The display class carries overflow-wrap:break-word
   and hyphens:auto, which exists so a 381 px word like INTEGRITETSPOLICY cannot push
   the document sideways -- and applied here it broke "tagga" as TAG-GA at 375, which
   reads as a typo rather than as a line break. The words in this heading are all short
   enough to wrap at their spaces, so the safety net is not needed and its cost is
   visible. Measured after: no horizontal overflow from 320 to 1920. */
.ig__ord h2 { hyphens: manual; }

/* Their own tag, set as the object it is rather than as a sentence. --guld-text,
   not --guld: measured 4.91:1 on cream against 2.60:1, and this is type. */
.ig__tagg {
  margin: var(--s-4) 0 0;
  font-family: var(--f-display);
  font-size: var(--t-md);
  letter-spacing: 0.04em;
  color: var(--guld-text);
}

/* .ig__handle är borta 2026-08-17 tillsammans med markupen den klädde -- se notisen
   i tools/instagram.py. Regeln raderas i stället för att lämnas kvar: inget bygge
   producerar klassen längre, och en regel utan element är en fälla nästa gång någon
   söker efter var handtaget stylas och tror att det finns. */

/* --- the scene ---------------------------------------------------------- */

.ig__scen {
  position: relative;
  width: var(--tel-b);
  max-width: 100%;
  justify-self: center;
}

/* --- the phone, drawn -------------------------------------------------- */

/* Generic on purpose: no maker's mark, no logo, no recognisable model. A shell,
   a screen, a speaker slot and a home line is all a phone needs to read as one. */
.ig__telefon {
  position: relative;
  z-index: 2;
  width: 100%;
  aspect-ratio: 9 / 17.5;
  padding: 0.55rem;
  border-radius: calc(var(--skarm-r) + 0.55rem);
  background: linear-gradient(160deg, #3a3a3e, #16161a 42%, #2a2a2f);
  box-shadow:
    0 2px 0 rgb(255 255 255 / 0.14) inset,
    0 26px 50px rgb(43 26 14 / 0.42),
    0 4px 10px rgb(43 26 14 / 0.3);
}

.ig__hogtalare {
  position: absolute;
  top: 0.28rem;
  left: 50%;
  translate: -50% 0;
  width: 22%;
  height: 0.2rem;
  border-radius: 1rem;
  background: rgb(255 255 255 / 0.22);
}

.ig__hemlinje {
  position: absolute;
  bottom: 0.2rem;
  left: 50%;
  translate: -50% 0;
  width: 30%;
  height: 0.14rem;
  border-radius: 1rem;
  background: rgb(255 255 255 / 0.28);
}

.ig__skarm {
  position: relative;
  height: 100%;
  border-radius: var(--skarm-r);
  overflow: hidden;
  background: #0d0b09;
}

/* --- the camera view --------------------------------------------------- */

.ig__vy { position: absolute; inset: 0; }
.ig__vy img,
.ig__vybild {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The focus frame. Corner brackets only, drawn with two gradients rather than four
   elements: a full rectangle reads as a border on the screen, brackets read as a
   camera. */
.ig__fokus {
  position: absolute;
  inset: 22% 16% 26%;
  --hl: rgb(245 239 228 / 0.9);
  background:
    linear-gradient(var(--hl), var(--hl)) 0 0 / 1.1rem 2px no-repeat,
    linear-gradient(var(--hl), var(--hl)) 0 0 / 2px 1.1rem no-repeat,
    linear-gradient(var(--hl), var(--hl)) 100% 0 / 1.1rem 2px no-repeat,
    linear-gradient(var(--hl), var(--hl)) 100% 0 / 2px 1.1rem no-repeat,
    linear-gradient(var(--hl), var(--hl)) 0 100% / 1.1rem 2px no-repeat,
    linear-gradient(var(--hl), var(--hl)) 0 100% / 2px 1.1rem no-repeat,
    linear-gradient(var(--hl), var(--hl)) 100% 100% / 1.1rem 2px no-repeat,
    linear-gradient(var(--hl), var(--hl)) 100% 100% / 2px 1.1rem no-repeat;
}

/* The shutter. A picture of a control, never a control: no button element, no
   focus, no pointer events. */
.ig__slutare {
  position: absolute;
  bottom: 1.1rem;
  left: 50%;
  translate: -50% 0;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  border: 2px solid rgb(245 239 228 / 0.95);
  /* A ring on a busy photograph disappears. The dark halo outside it is what makes
     it read as a control on top of a picture rather than as a mark in the picture --
     measured by looking: over the table shot the bare ring was invisible. */
  box-shadow:
    0 0 0 0.28rem rgb(13 11 9 / 0.4) inset,
    0 0 0 1px rgb(13 11 9 / 0.55),
    0 2px 10px rgb(13 11 9 / 0.5);
  background: rgb(245 239 228 / 0.2);
}

/* The flash. Transparent until the script fires it, and it never fires at all in
   the two still directions. */
.ig__blixt {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
}

/* --- the filmstrip, inside the screen -------------------------------------

   After the reference Dennis sent: the phone's own photo viewer. One picture fills
   the screen and a tight row of small ones runs along the bottom, with the current
   one lifted out of the row. Two things in that reference are what make it read as a
   device and not as a gallery: the thumbnails are SMALL and CLOSE, almost touching,
   and the strip sits on a dark bar rather than floating on the picture.
   -------------------------------------------------------------------------- */

.ig__remsa {
  position: absolute;
  z-index: 2;
  inset: auto 0 0;
  list-style: none;
  margin: 0;
  padding: 0.45rem 0.5rem calc(0.45rem + 0.5rem);   /* room for the home line */
  display: flex;
  gap: 3px;
  align-items: flex-end;
  justify-content: center;
  background: linear-gradient(to bottom, rgb(13 11 9 / 0), rgb(13 11 9 / 0.82) 38%, rgb(13 11 9 / 0.92));
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.ig__remsa::-webkit-scrollbar { display: none; }
.ig__remsa:focus-visible { outline: 2px solid var(--guld-ljus); outline-offset: -3px; }

.ig__bild { margin: 0; flex: none; }
.ig__bild a {
  display: block;
  width: var(--minia-b);
  aspect-ratio: var(--minia-r);
  overflow: hidden;
  border-radius: 2px;
  background: rgb(245 239 228 / 0.12);
  transition: width 220ms ease, aspect-ratio 220ms ease;
}
.ig__bild img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* The current one, raised out of the row. In the reference it is both wider and
   taller than its neighbours, which is what makes the row read as a position
   indicator rather than as decoration.

   THE LAST ONE IS RAISED BY DEFAULT, in CSS, matching the picture the phone shows
   before any script runs. Measured on 2026-08-10: with the marker set only by the
   script, the ogonblick direction had NO raised thumbnail at all and the strip read
   as unfinished rather than as still. A state that only exists once JavaScript has
   run is a state the page does not have. The script overrides this the moment it
   moves. */
.ig__bild:last-child a,
.ig__bild[data-ig-nu="ja"] a {
  width: var(--minia-nu-b);
  aspect-ratio: var(--minia-nu-r);
  box-shadow: 0 0 0 1.5px rgb(245 239 228 / 0.95);
}

/* ...and the default gives way as soon as anything is actually marked. */
.ig__remsa:has([data-ig-nu]) .ig__bild:last-child:not([data-ig-nu]) a {
  width: var(--minia-b);
  aspect-ratio: var(--minia-r);
  box-shadow: none;
}

.ig__bild a:focus-visible { outline: 2px solid var(--guld-ljus); outline-offset: 2px; }

/* The camera interface has to move up out of the strip's way. */
.ig__slutare { bottom: 3.3rem; }
.ig__fokus { inset: 20% 16% 34%; }

/* ==========================================================================
   TRE RIKTNINGAR
   ========================================================================== */

/* --- A. KAMERAN. The shutter fires and the strip advances. -------------- */

/* Motion, and the whole obligation is in instagram.js: stops on hover, on keyboard
   focus and on tap, stands still off screen and in a hidden tab, and under
   prefers-reduced-motion never starts -- the phone shows a dish, the strip shows all
   six, and nothing a visitor would have seen is missing. */
.ig--kamera .ig__vybild { transition: opacity 260ms ease; }
.ig[data-ig-blixt="ja"] .ig__blixt { animation: ig-blixt 420ms ease-out; }
@keyframes ig-blixt {
  0%   { opacity: 0; }
  12%  { opacity: 0.92; }
  100% { opacity: 0; }
}
.ig[data-ig-blixt="ja"] .ig__slutare { animation: ig-tryck 420ms ease-out; }
@keyframes ig-tryck {
  0%, 100% { scale: 1; }
  18%      { scale: 0.86; }
}

@media (prefers-reduced-motion: reduce) {
  .ig .ig__blixt,
  .ig .ig__slutare { animation: none !important; }
}

/* --- B. ÖGONBLICKET. The strip inside, the plates outside. -------------- */

/* Same phone and same strip, and the difference is what surrounds it: the five
   other pictures lie scattered around the device as prints, as if just taken. They
   are drawn from the same six by CSS alone -- there is no second copy of the list --
   using the strip's own items, lifted out of the row and enlarged. That is why this
   direction cannot animate: an item cannot be in the row and on the table at once. */
/* THE PANEL WENT ROUND THE WRONG THING. It was a dark table under the phone AND the
   prints, on my reading of "a section of their own on a black table" -- and Dennis
   meant inside the screen, a small black box where the thumbnails sit. So the scene
   has no ground of its own again, and the box is on the strip further down. */
.ig--ogonblick .ig__scen { width: min(25.5rem, 75vw); padding: 3.5rem 0; }
.ig--ogonblick .ig__telefon { margin-inline: auto; width: var(--tel-b); }
/* NOT pre-pressed any more. It was drawn mid-press while this direction was still --
   a frozen gesture standing in for a missing one -- and a shutter that is already down
   cannot be seen going down. Now it presses for real on every shot, like kamera's.

   And it sits higher, on Dennis's ask. Down at 3.3rem it was pressed against the
   filmstrip's top edge with the two gestures -- a shutter going down and a thumbnail
   rising -- happening in the same 20 px. Moved up it has air under it, and the focus
   frame moves with it so the camera's three parts stay in the same order they are in
   on a real one: frame, shutter, strip. */
.ig--ogonblick .ig__slutare { bottom: 5.4rem; }
.ig--ogonblick .ig__fokus { inset: 12% 16% 46%; }

/* THE BLACK IS A SOLID BAR WELDED TO THE BOTTOM OF THE SCREEN, edge to edge. Two
   corrections got it here: first the panel went around the phone instead of inside it,
   then the strip became a floating box with a gap under it. It sits flush now, full
   width, and it is part of the device rather than something resting in it.

   No border-radius on it, deliberately. The screen already has overflow:hidden and its
   own 1.6rem corners, so a square bar is clipped to exactly that curve -- and a radius
   written here would be the screen's number in a second place, free to drift from it.
   Let the clip do it.

   No bottom padding either: the home line lives on the shell, in the 0.55rem of
   padding outside the screen, so there is nothing down there to clear. */
.ig--ogonblick .ig__remsa {
  inset: auto 0 0;
  width: auto;
  max-width: none;
  margin-inline: 0;
  /* The top padding IS the fade. The bar grows upward by 1.7rem of ramp so the
     thumbnails still sit on solid black while the black rises out of the photograph
     instead of cutting it. */
  padding: 1.7rem 0.5rem 0.5rem;
  /* THE BAR MAY NOT MOVE, only the pictures in it. Dennis: the little pictures can
     jump, the faded black must not. It was moving 11,6 px -- measured, height and top
     edge both -- because the row's height came from its content and the raised
     thumbnail is the tallest thing in it. Mid-swap the outgoing and incoming ones are
     both part way through the 220 ms transition, so the tallest item briefly is not as
     tall, and the bar sank and rose with it.
     Fixing the height stops that by construction rather than by tuning: 1.7rem of ramp
     plus the raised thumbnail plus 0.5rem, derived from the same tokens the thumbnails
     use, so changing a thumbnail size cannot leave this number behind. */
  height: calc(1.7rem + var(--minia-nu-h) + 0.5rem);
  border-radius: 0;
  /* Stops in absolute lengths, not percentages: the ramp has to finish exactly where
     the thumbnails begin, and a percentage moves that point every time the row's
     height changes. Same reason the hero's veil is written in rem. */
  background: linear-gradient(
    to bottom,
    rgb(8 7 6 / 0) 0,
    rgb(8 7 6 / 0.55) 0.85rem,
    rgb(8 7 6 / 0.94) 1.6rem,
    rgb(8 7 6 / 0.94) 100%);
  /* No hairline any more. A drawn edge and a fade are two answers to the same
     question, and having both means the bar has a top and also does not. */
}
/* Hidden everywhere but one direction. display:none, so nothing is painted and
   nothing is measured in the other two. */
.ig__spridda { display: none; }
.ig--ogonblick .ig__spridda {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* HELA UTLÄGGNINGEN HÄNGER PÅ ETT TAL. Kortens bredd, deras padding och alla sex
     lägen räknas mot --spridd-k, så en annan brytpunkt flyttar EN siffra i stället
     för tolv. Det är samma skäl som Kenar-scenens variabler har: tolv tal som måste
     följas åt blir förr eller senare elva som gör det. */
  --spridd-k: 1;
}
.ig--ogonblick .ig__spridd {
  position: absolute;
  width: calc(6.5rem * var(--spridd-k));
  padding: calc(0.35rem * var(--spridd-k)) calc(0.35rem * var(--spridd-k))
           calc(0.3rem * var(--spridd-k));
  background: var(--papper);
  box-shadow: 0 10px 22px rgb(43 26 14 / 0.28);
  /* scale, not transform, so it composes with the rotate each print is given below
     instead of overwriting it. Six scatter angles written by hand would be lost the
     moment a transform: scale() landed on the same element. */
  transition: scale 320ms cubic-bezier(0.2, 0.9, 0.3, 1.25),
              box-shadow 320ms ease;
}
.ig--ogonblick .ig__spridd img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

/* THE PRINT THE PHONE IS SHOWING lifts off the table. Dennis, 2026-08-11: they can
   pop out a bit when that picture is the one selected in the phone.

   There used to be an opacity transition on the image here, for a fade the script
   ran when it swapped a print's source. Both are gone. Fading a photograph to zero
   on a white paper card is a WHITE BLINK, and it fired on the same frame as the
   shutter -- so the flash looked like it was leaking out of the screen and onto the
   table. Nothing changes source any more, so there is nothing to fade.

   1.07, and the overshoot in the easing is what makes it a pop rather than a zoom:
   it passes the mark and settles back. 6.5rem grows by about 7 px, which is visible
   next to five still ones and small enough that the scatter does not turn into a
   layout. The shadow deepens with it, because a card that lifts casts further.

   Raised above its neighbours too -- the prints overlap at the edges, and half a
   lifted card behind a flat one reads as a glitch rather than as depth. */
.ig--ogonblick .ig__spridd[data-ig-nu="ja"] {
  scale: 1.07;
  z-index: 2;
  box-shadow: 0 16px 30px rgb(43 26 14 / 0.34);
}

/* THE LAST PRINT IS LIFTED BEFORE ANY SCRIPT RUNS, matching the picture the phone
   shows on a still page -- the same reason the last thumbnail is raised in CSS.
   A state that only exists once JavaScript has run is a state the page does not
   have, and this one has to be right under prefers-reduced-motion too, where the
   script marks once and then never touches it again. */
.ig--ogonblick .ig__spridd:last-child { scale: 1.07; z-index: 2; }
.ig--ogonblick .ig__spridda:has([data-ig-nu]) .ig__spridd:last-child:not([data-ig-nu]) {
  scale: 1;
  z-index: auto;
}

@media (prefers-reduced-motion: reduce) {
  /* The mark stays, the travel goes: which dish the phone is on is information, and
     the pop is only how it was delivered. */
  .ig--ogonblick .ig__spridd { transition: none; }
}
/* Six places on the table, written out rather than generated: an nth-child rotation
   looks mechanical, and the whole point of a scatter is that it is not a pattern.
   They stay INSIDE the table now -- negative offsets would hang a print off the edge
   of the very surface it is supposed to be lying on. */
.ig--ogonblick .ig__spridd:nth-child(1) { top: calc(0.5rem * var(--spridd-k)); left: 0; rotate: -6deg; }
.ig--ogonblick .ig__spridd:nth-child(2) { top: calc(7.5rem * var(--spridd-k)); left: calc(-1rem * var(--spridd-k)); rotate: 4deg; }
.ig--ogonblick .ig__spridd:nth-child(3) { bottom: calc(0.5rem * var(--spridd-k)); left: calc(1.5rem * var(--spridd-k)); rotate: -3deg; }
.ig--ogonblick .ig__spridd:nth-child(4) { top: 0; right: calc(0.5rem * var(--spridd-k)); rotate: 5deg; }
.ig--ogonblick .ig__spridd:nth-child(5) { top: calc(8rem * var(--spridd-k)); right: calc(-1rem * var(--spridd-k)); rotate: -5deg; }
.ig--ogonblick .ig__spridd:nth-child(6) { bottom: calc(1rem * var(--spridd-k)); right: calc(1rem * var(--spridd-k)); rotate: 3deg; }

@media (max-width: 57.999rem) {
  /* KORTEN FINNS PÅ TELEFON OCKSÅ, Dennis 2026-08-17: "polaroidbilderna runt om
     mobilen SAKNAS på mobil", och den generella regeln han gav i samma andetag --
     allt som finns på desktop ska finnas på mobil.

     HÄR STOD MOTSATSEN, och den gamla raden hade rätt om sitt eget fall: sex kort
     på 6,5rem runt en 315 px scen ÄR sex kort ovanpå varandra. Felet var att korten
     behöll sin desktopstorlek i en scen som krympt -- alltså inte att utläggningen
     inte gick att göra, utan att den aldrig skalades.

     0,58 ÄR RÄKNAT UR GÅNGEN BREDVID TELEFONEN, inte ur scenens bredd, och de två
     talen är olika: scenen går 480 -> 315 px (0,656) men telefonen bara 272 -> 195
     (0,717), så gången vid sidan om krymper hårdare än scenen -- 104 px -> 60, som
     är 0,577. Skalar man efter scenen blir korten 68 px i en 60 px gång och lägger
     sig längre in över telefonen än de gör på skärmen. Höjdled stämmer på samma
     tal: scenens höjd går 641 -> 379, alltså 0,591.

     PADDINGEN MÅSTE TILLBAKA. Den nollades när korten göms, och utan den är scenen
     exakt lika hög som telefonen -- då finns ingen yta ovanför eller under där de
     två övre och de två nedre korten ska ligga. 2rem är desktops 3,5 gånger samma
     0,58. */
  .ig--ogonblick .ig__scen { width: min(17rem, 71vw); padding: 2rem 0; }
  .ig--ogonblick .ig__spridda { --spridd-k: 0.58; }
}

/* --- C. FLÖDET. The phone alone, and the strip is the whole interface. --- */

/* The closest of the three to the reference: no feed outside the device at all. The
   picture is large, the strip is the only navigation, and the camera interface is
   dropped entirely -- this is a viewer, not a camera. */
.ig--flode .ig__scen { width: min(19rem, 62vw); }
.ig--flode .ig__fokus,
.ig--flode .ig__slutare { display: none; }
.ig--flode .ig__remsa { padding-top: 0.6rem; }
.ig--flode .ig__bild a { width: 1.7rem; }
.ig--flode .ig__bild[data-ig-nu="ja"] a { width: 2.5rem; }
/* A thin toolbar under the strip, the way the reference has one: share, like, info.
   Drawn, decorative, and not controls -- so it is a ::after and cannot take focus. */
.ig--flode .ig__skarm::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 2.2rem;
  z-index: 3;
  background:
    radial-gradient(circle 0.42rem at 22% 45%, rgb(245 239 228 / 0.5) 96%, transparent) no-repeat,
    radial-gradient(circle 0.42rem at 50% 45%, rgb(245 239 228 / 0.5) 96%, transparent) no-repeat,
    radial-gradient(circle 0.42rem at 78% 45%, rgb(245 239 228 / 0.5) 96%, transparent) no-repeat,
    rgb(13 11 9 / 0.92);
  pointer-events: none;
}
.ig--flode .ig__remsa { bottom: 2.2rem; padding-bottom: 0.5rem; }
