@import url("_fonts.css");

/* ============================================================
   Invitation · fest.senzi.dk
   Kuvertens og brevets geometri hænger sammen:
     --ph  = foldehøjde = --lh / 3   (brevet er foldet i tre)
     --eh  må ikke være mindre end den sammenfoldede, nedskalerede
            brevhøjde (--ph * --lscale), ellers stikker brevet ud
            under kuvertens forside inden det er åbnet.
   ============================================================ */

:root{
  --ink:      #2c2a27;
  --ink-soft: #5f5a52;
  --paper:    #fbf7ec;
  --paper-2:  #f3ecdb;
  --red:      #c8352d;
  --blue:     #1b3a5c;
  --gold:     #b08b4f;
  --bg:       #16212e;
  --bg-2:     #22344a;

  /* Scenegeometri – desktop.
     --lh skal gå op i 3, ellers får panelerne en pixelsøm imellem sig,
     og --lw/--lh skal have invitationsbilledets format, 2:3 (1024×1536),
     ellers bliver billedet beskåret af .sheet__img. */
  --lw: 500px;            /* brevbredde            */
  --lh: 750px;            /* brevhøjde             */
  --ph: 250px;            /* = --lh / 3            */
  --ew: 520px;            /* kuvertbredde          */
  --eh: 300px;            /* kuverthøjde           */
  --sh: 750px;            /* scenehøjde = --lh, så der ikke er luft under brevet */
  --tofs: 31px;           /* modtagernavnene på kuvertens forside */
  --lscale: .85;          /* brevets skala i kuverten */
  --ltop: calc(var(--sh) - 24px - var(--ph));
}

@media (max-width: 680px){
  :root{
    --lw: 368px;  --lh: 552px;  --ph: 184px;
    --ew: 368px;  --eh: 282px;  --sh: 552px;
    --lscale: .82; --tofs: 25px;
  }
}

*,*::before,*::after{ box-sizing:border-box; }

body{
  margin:0;
  font-family:"Playfair Display", Georgia, serif;
  color:var(--ink);
  background:
    radial-gradient(1200px 700px at 50% -10%, var(--bg-2) 0%, var(--bg) 62%),
    var(--bg);
  -webkit-font-smoothing:antialiased;
}

img{ max-width:100%; height:auto; display:block; }


/* ============================================================
   1 · SCENEN
   ============================================================ */

.scene{
  min-height:100svh;
  display:grid;
  place-items:center;
  padding:12px 0;
  overflow:hidden;
}
.scene__inner{ display:grid; justify-items:center; gap:1.25rem; }

/* Skaleres så scenen altid kan være i vinduet. --scale sættes af app.js. */
/* Scenen er høj nok til det udfoldede brev, men kuverten fylder kun
   nederste tredjedel. Lukket løftes hele scenen derfor op med --shift,
   så kuverten står midt i vinduet; når brevet kommer op, glider den
   tilbage på plads, og brevet lander centreret. */
.stage{
  position:relative;
  width:var(--ew);
  height:var(--sh);
  --shift:calc(var(--eh) / 2 - var(--sh) / 2);
  perspective:1700px;          /* giver brevets foldninger dybde */
  transform:scale(var(--scale,1)) translateY(var(--shift));
  transform-origin:top center;
  transition:transform 1.05s cubic-bezier(.34,1.12,.4,1) .62s;
  /* app.js sætter margin-bottom, så den skalerede højde passer i flowet */
}
.stage.is-open{ --shift:0px; }


/* ---------- Kuverten ---------- */

.envelope{
  position:absolute;
  left:0; bottom:0; z-index:3;
  width:var(--ew); height:var(--eh);
  perspective:1400px;          /* eget perspektiv til klappen */
  cursor:pointer;
  transition:transform .75s cubic-bezier(.4,0,.2,1) 1.45s,
             opacity   .6s ease 1.55s;
}
.envelope:focus-visible{ outline:3px solid var(--gold); outline-offset:10px; border-radius:4px; }

.is-open .envelope{
  transform:translateY(calc(var(--eh) * .9)) scale(.94);
  opacity:0;
  pointer-events:none;
}

/* Vendingen. Forside og bagside er to flader i ét og samme 3D-rum, og de
   er sammenfaldende. Hver skubbes derfor 1 px ud ad sin egen normal, så
   den flade, der vender mod skærmen, altid ligger nærmest – ellers
   afgør browseren selv, hvem der tegnes øverst. */
.env__flip{
  position:absolute; inset:0;
  transform-style:preserve-3d;
  transform:rotateY(0deg);
  transition:transform 1s cubic-bezier(.5,.03,.25,1);
}
.is-flipped .env__flip{ transform:rotateY(180deg); }

/* backface-visibility hører kun til de to flader – IKKE til klappen.
   Den skal netop kunne ses fra vrangen, når den er vippet op. */
.env__side{
  position:absolute; inset:0;
  border-radius:3px;
  backface-visibility:hidden;
  box-shadow:0 26px 50px -18px rgba(0,0,0,.6);
}

/* forsiden – airmail-striber med papir indeni */
.env__side--front{
  transform:translateZ(1px);
  overflow:hidden;
}

/* Bagsiden må IKKE klippe: klappen vipper op uden for kuvertens kasse,
   ligesom brevets .fold. Klipningen ligger i .env__back-paper. */
.env__side--back{
  transform:rotateY(180deg) translateZ(1px);
  transform-style:preserve-3d;
}

.env__stripes{
  position:absolute; inset:0;
  background:repeating-linear-gradient(45deg,
      var(--red)   0 11px, var(--paper) 11px 22px,
      var(--blue) 22px 33px, var(--paper) 33px 44px);
}
.env__paper{
  position:absolute; inset:9px;
  background:var(--paper);
  background-image:radial-gradient(rgba(0,0,0,.022) 1px, transparent 1px);
  background-size:4px 4px;
}

.paravion{
  position:absolute; left:16px; bottom:14px;
  display:grid; gap:1px;
  font-family:"Playfair Display",serif; font-style:italic;
  font-size:15px; letter-spacing:.06em;
  color:var(--paper); background:var(--blue);
  padding:5px 12px 6px; border-radius:2px;
  transform:rotate(-1.5deg);
}
.paravion small{
  font-style:normal; font-size:8.5px; letter-spacing:.3em;
  text-transform:uppercase; opacity:.85;
}

/* Takkerne skal kun sidde i kanten. Én gennemgående maske af cirkler
   ville punktere hele mærket, så den lægges som fem lag: fire smalle
   striber langs kanterne, hver med sin halve cirkel skåret ud, og en
   massiv midte. Lagene lægges sammen, så midten forbliver hel. */
.stamp{
  position:absolute; right:16px; top:14px;
  width:66px; height:77px;
  --tak: 4.2px;                 /* takkens dybde  */
  --trin: 11px;                 /* afstand mellem takker */
  display:grid; place-content:center; gap:2px;
  text-align:center;
  background:
    linear-gradient(150deg, #e9d8c4, #dcc4a6);
  transform:rotate(3deg);
  -webkit-mask:
    radial-gradient(circle var(--tak) at 50% 0,    transparent 98%, #000) left top / var(--trin) var(--tak) repeat-x,
    radial-gradient(circle var(--tak) at 50% 100%, transparent 98%, #000) left bottom / var(--trin) var(--tak) repeat-x,
    radial-gradient(circle var(--tak) at 0 50%,    transparent 98%, #000) left top / var(--tak) var(--trin) repeat-y,
    radial-gradient(circle var(--tak) at 100% 50%, transparent 98%, #000) right top / var(--tak) var(--trin) repeat-y,
    linear-gradient(#000, #000) center / calc(100% - var(--tak) * 2) calc(100% - var(--tak) * 2) no-repeat;
          mask:
    radial-gradient(circle var(--tak) at 50% 0,    transparent 98%, #000) left top / var(--trin) var(--tak) repeat-x,
    radial-gradient(circle var(--tak) at 50% 100%, transparent 98%, #000) left bottom / var(--trin) var(--tak) repeat-x,
    radial-gradient(circle var(--tak) at 0 50%,    transparent 98%, #000) left top / var(--tak) var(--trin) repeat-y,
    radial-gradient(circle var(--tak) at 100% 50%, transparent 98%, #000) right top / var(--tak) var(--trin) repeat-y,
    linear-gradient(#000, #000) center / calc(100% - var(--tak) * 2) calc(100% - var(--tak) * 2) no-repeat;
}
.stamp__num{
  font-size:34px; font-weight:700; line-height:1;
  color:var(--red); font-family:"Playfair Display",serif;
}
.stamp__land{
  font-size:7.5px; letter-spacing:.22em; text-transform:uppercase;
  color:var(--blue);
}

.postmark{
  position:absolute; right:78px; top:22px;
  width:74px; height:74px; border-radius:50%;
  border:2px solid rgba(27,58,92,.45);
  display:grid; place-items:center;
  transform:rotate(-13deg);
  opacity:.6;
}
.postmark::before,
.postmark::after{
  content:""; position:absolute; left:6px; right:6px; height:1.5px;
  background:rgba(27,58,92,.45);
}
.postmark::before{ top:18px; } .postmark::after{ bottom:18px; }
.postmark span{
  font-size:10px; letter-spacing:.07em; color:rgba(27,58,92,.75);
}

/* Modtagerne – det eneste håndskrevne på forsiden. Navnene sættes af
   app.js ud fra ?til= i adressen, og linjelængden styrer skriftgraden,
   så lange rækker af navne ikke løber ud over kuvertens kant. */
.env__to{
  position:absolute; left:30%; right:7%; top:38%;
  margin:0;
  font-family:Caveat, cursive; font-size:var(--tofs); line-height:1.14;
  color:var(--blue);
  transform:rotate(-1.2deg);
}
.env__to-label{
  display:block; font-size:.5em; line-height:1;
  color:var(--ink-soft); margin-bottom:.1em;
}
.env__to-names{ display:block; }
.env__to.is-long{  font-size:calc(var(--tofs) * .82); top:35%; }
.env__to.is-xlong{ font-size:calc(var(--tofs) * .66); top:32%; }


/* ---------- Kuvertens bagside ---------- */

.env__back-paper{
  position:absolute; inset:0;
  border-radius:3px;
  overflow:hidden;
  background:linear-gradient(176deg, #f6efdf 0%, #e9ddc4 100%);
  backface-visibility:hidden;
}

/* bundklappen – den eneste anden søm, man ser på en kuvertbagside */
.env__bottom{
  position:absolute; inset:0;
  clip-path:polygon(0 100%, 50% 38%, 100% 100%);
  background:linear-gradient(to top, #faf5e9, #eee5cf);
  filter:drop-shadow(0 -1px 1px rgba(0,0,0,.09));
}

/* kuvertens indre. Ligger under klappen og bliver først synligt,
   når den vipper op. */
.env__mouth{
  position:absolute; left:0; top:0;
  width:100%; height:calc(var(--eh) * .62);
  clip-path:polygon(0 0, 100% 0, 50% 100%);
  background:linear-gradient(#b5a382 0%, #cdbd9c 45%, #e0d5ba 100%);
}

/* Afsenderen sidder på klappen, i dens øverste tredjedel og midt for.
   Den følger derfor med op, når kuverten åbnes – og fader ud med det
   samme, for ellers ville skriften stå spejlvendt på klappens vrang,
   når den er vippet helt om. */
.env__from{
  position:absolute; left:0; right:0; top:13%; margin:0;
  text-align:center;
  font-family:Caveat, cursive; line-height:1.1;
  transition:opacity .3s ease;
}
.is-open .env__from{ opacity:0; }

.env__from-label{
  display:block;
  font-family:"Playfair Display", serif;
  font-size:8.5px; letter-spacing:.24em; text-transform:uppercase;
  color:var(--ink-soft); margin-bottom:3px;
}
.env__from-name{ display:block; font-size:26px; color:var(--blue); }

/* Klappen – det er her, kuverten åbnes, og derfor er den tegnet tydeligt
   op: den ydre trekant er selve kantstregen, den indre (2 px mindre) er
   papiret, og skyggen løfter V'et fri af bagsiden. */
.env__flap{
  position:absolute; left:0; top:0;
  width:var(--ew); height:calc(var(--eh) * .62);
  transform-origin:top center;
  transform:translateZ(.6px) rotateX(0deg);
  transition:transform .95s cubic-bezier(.62,-0.10,.3,1);
}
.is-open .env__flap{ transform:translateZ(.6px) rotateX(177deg); }

.env__flap-inner{
  position:absolute; inset:0;
  clip-path:polygon(0 0, 100% 0, 50% 100%);
  background:rgba(150,119,66,.85);
  filter:drop-shadow(0 6px 11px rgba(0,0,0,.32));
}
.env__flap-inner::after{
  content:""; position:absolute; inset:0;
  clip-path:polygon(2px 2px, calc(100% - 2px) 2px, 50% calc(100% - 5px));
  background:linear-gradient(184deg, #fbf6ea 0%, #ebdfc5 100%);
}

.env__hint{
  position:absolute; left:0; right:0; bottom:-42px;
  margin:0; text-align:center;
  font-family:Caveat, cursive; font-size:22px; color:#cbb98f;
  animation:breathe 2.6s ease-in-out infinite;
}
.is-open .env__hint{ opacity:0; transition:opacity .3s; animation:none; }
@keyframes breathe{ 0%,100%{opacity:.55; transform:translateY(0)} 50%{opacity:1; transform:translateY(3px)} }


/* ---------- Brevet ---------- */

/* Brevet står i scenens koordinatsystem, ikke kuvertens. Lukket ligger det
   bag hele kuverten (z-index 2 < 3) og er dermed skjult; når det er kommet
   op, lægger det sig foran alting (z-index 6). */
.letter{
  position:absolute;
  left:calc((var(--ew) - var(--lw)) / 2);
  top:var(--ltop);
  width:var(--lw);
  height:var(--ph);              /* sammenfoldet: kun første tredjedel */
  z-index:2;
  transform-origin:bottom center;
  transform:translateY(0) scale(var(--lscale));
  transform-style:preserve-3d;
  transition:transform 1.05s cubic-bezier(.34,1.12,.4,1) .62s,
             z-index   0s .62s;
}
.is-open .letter{
  transform:translateY(calc(var(--ltop) * -1)) scale(1);
  z-index:6;
}

/* De tre foldepaneler – 2 og 3 er hængslet i hinandens underkant.
   .fold er kun hængsel og må ikke have overflow:hidden, for den
   indeholder det næste panel uden for sin egen kasse. Klipningen
   ligger derfor i .pane. */
.fold{
  position:absolute; left:0; top:0;
  width:var(--lw); height:var(--ph);
  transform-style:preserve-3d;
}
.fold--2, .fold--3{
  top:100%;
  transform-origin:top center;
}

/* selve papiret: uigennemsigtigt og klippet til én tredjedel */
.pane{
  position:absolute; inset:0;
  overflow:hidden;
  background:var(--paper);
  backface-visibility:hidden;
}
.fold--1 > .pane{ box-shadow:0 18px 34px -20px rgba(0,0,0,.55); }
/* Sammenfoldet ligger panel 2 og 3 oven i panel 1. De er indbyrdes
   koplanare, så translateZ skubber dem bagud og afgør rækkefølgen –
   ellers kan browseren tegne panel 3 hen over teksten på panel 1.
   Panel 3 er vendt to gange, så dens lokale +Z peger mod skærmen igen;
   derfor negativt fortegn dér. */
.fold--2{
  transform:rotateX(-179.9deg) translateZ(2px);
  transition:transform .9s cubic-bezier(.45,.05,.2,1) 1.72s;
}
.fold--3{
  transform:rotateX(179.9deg) translateZ(-4px);
  transition:transform .9s cubic-bezier(.45,.05,.2,1) 2.42s;
}
.is-open .fold--2,
.is-open .fold--3{ transform:rotateX(0deg); }

/* foldelinjen bliver siddende i papiret bagefter */
.fold--2::before, .fold--3::before{
  content:""; position:absolute; left:0; right:0; top:0; height:14px;
  background:linear-gradient(rgba(0,0,0,.09), rgba(0,0,0,0));
  pointer-events:none; z-index:3;
}

/* hvert panel er et vindue ned i det samme, fulde ark */
.sheet{
  position:absolute; left:0;
  top:calc(var(--slice, 0) * var(--ph) * -1);
  width:var(--lw); height:var(--lh);
}

.sheet__img{
  display:block;
  width:100%; height:100%;
  max-width:none;
  object-fit:cover;
}


/* ============================================================
   2 · TILGÆNGELIGHED
   ============================================================ */

@media (prefers-reduced-motion: reduce){
  .stage, .envelope, .env__flip, .env__flap, .letter, .fold--2, .fold--3{
    transition-duration:.001s !important;
    transition-delay:0s !important;
  }
  .env__hint{ animation:none; opacity:.8; }
}
