/* Cormorant Garamond 500 + 500 italic, self-hosted (Google Fonts subsets): latin-ext (ğ ş İ) only loads where those letters appear */
@font-face { font-family:'Cormorant Garamond'; font-style:normal; font-weight:500; font-display:swap; src:url(assets/cormorant-500-latin.woff2) format('woff2');
             unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family:'Cormorant Garamond'; font-style:normal; font-weight:500; font-display:swap; src:url(assets/cormorant-500-latin-ext.woff2) format('woff2');
             unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
@font-face { font-family:'Cormorant Garamond'; font-style:italic; font-weight:500; font-display:swap; src:url(assets/cormorant-500-italic-latin.woff2) format('woff2');
             unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family:'Cormorant Garamond'; font-style:italic; font-weight:500; font-display:swap; src:url(assets/cormorant-500-italic-latin-ext.woff2) format('woff2');
             unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF; }
/* Georgian fallback in --font: on the EN/TR pages it draws only the "ქართული" language button; size-adjust shrinks it to sit with Cormorant's small x-height */
@font-face { font-family:'Georgian'; src:url(assets/noto-sans-georgian.woff2) format('woff2'); font-weight:100 900; font-display:swap;
             size-adjust:80%; unicode-range:U+10A0-10FF, U+1C90-1CBF, U+2D00-2D2F; }
/* KA page text: BPG Mikheil Stefane, a broad-pen face like Cormorant, with its own digits + punctuation so "28", "2027" match the letters;
   size-adjust 112% gives its letters Cormorant's x-height.
   It has no Mtavruli capitals, so the capital labels take Noto Serif Georgian's. Both are subsets; licences in assets/FONTS-LICENSE.txt */
@font-face { font-family:'Georgian Pen'; src:url(assets/bpg-mikheil-stefane.woff2) format('woff2'); font-display:swap;
             size-adjust:112%; unicode-range:U+0020-0040, U+00B7, U+2013-2014, U+2019, U+10D0-10FF; }
@font-face { font-family:'Georgian Pen'; src:url(assets/noto-serif-georgian-caps.woff2) format('woff2'); font-display:swap;
             size-adjust:84%; unicode-range:U+1C90-1CBF; }
:root { --page:#f3ece0; --ink:#8f1d22; --font:'Cormorant Garamond','Georgian',Georgia,serif; color-scheme:light; }
* { box-sizing:border-box; }
html { background:var(--page); }   /* on html only: a body background would paint over the z-index:-1 surface layers */
body { margin:0; color:var(--ink); font-family:var(--font); }
body { -webkit-text-size-adjust:100%; }

/* browser surfaces in the card's ink: selection, keyboard focus, text caret */
::selection { background:var(--ink); color:var(--page); }
:focus-visible { outline:2px solid var(--ink); outline-offset:3px; }
svg a:focus-visible { outline-width:16px; outline-offset:24px; }   /* in card units (4000 wide): ~1.5–2.5px on screen */
html { caret-color:var(--ink); }

/* ---------- page surface: vignette, then paper grain on top (the grain also dithers the vignette so it can't band) ---------- */
body::before, body::after { content:''; position:fixed; inset:0; z-index:-1; pointer-events:none; }
/* phone values are ~2.5x desktop's: at phone size and brightness the desktop amounts read as a flat page */
body::before { background:radial-gradient(ellipse 80% 65% at 50% 50%, transparent 35%, rgba(60,25,10,.16) 100%); }
body::after { opacity:.10; mix-blend-mode:multiply; background-size:256px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E"); }
@media (min-width:860px) and (min-aspect-ratio:1/1) {
  body::before { background:radial-gradient(ellipse 75% 70% at 50% 50%, transparent 45%, rgba(60,25,10,.07) 100%); }
  body::after { opacity:.04; }
}

/* ---------- layout: mobile first (card fills the first screen, details below) ---------- */
.layout { display:flex; flex-direction:column; align-items:center;
          padding:calc(12px + env(safe-area-inset-top,0px)) max(12px, env(safe-area-inset-right,0px)) calc(72px + env(safe-area-inset-bottom,0px)) max(12px, env(safe-area-inset-left,0px)); }
.card { width:min(100%, calc((100svh - 84px) * 2 / 3)); aspect-ratio:2/3;   /* 84px = page padding + room for the "details below" cue */ position:relative; flex:none;
        box-shadow:0 1px 2px rgba(80,30,20,.08), 0 18px 50px -20px rgba(80,30,20,.35); border-radius:4px; overflow:hidden; background:#f7f1e6; }
.panel { width:100%; max-width:380px; margin-top:28px; text-align:center; opacity:0; }

/* desktop: card left, panel right, one screen */
@media (min-width:860px) and (min-aspect-ratio:1/1) {
  .layout { flex-direction:row; justify-content:center; gap:clamp(40px,6vw,96px); min-height:100svh; padding-block:24px; }
  .card { width:auto; height:calc(100svh - 48px); max-height:1100px; }
  .panel { width:340px; margin-top:0; }
}

/* ---------- side panel ---------- */
.when { font-style:italic; font-size:clamp(20px,2.2vw,26px); margin:0; }
.whereline { font-size:17px; letter-spacing:.02em; line-height:1.6; margin:8px 0 0; }
.where { color:inherit; padding:3px 6px; border-radius:6px; -webkit-box-decoration-break:clone; box-decoration-break:clone; text-decoration:none; transition:background .2s; }
.where:hover, .where:focus-visible { background:rgba(143,29,34,.08); }
/* drawn underline: an ink pen stroke as a background, cloned onto each line if the venue wraps; draws in after the panel appears */
.where > span { padding-bottom:5px; -webkit-box-decoration-break:clone; box-decoration-break:clone; background:left bottom / 100% 6px no-repeat
  url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 6' preserveAspectRatio='none'%3E%3Cpath d='M1 3.6C30 2.2 62 4.6 101 3.3S170 2.4 199 3.9' fill='none' stroke='%238f1d22' stroke-opacity='.75' stroke-width='1.3' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E"); }
.on .where > span { animation:underline .9s cubic-bezier(.45,.05,.55,.95) calc(var(--namesEnd, 6s) + 3s) both; }
@keyframes underline { from { background-size:0% 6px; } }
/* phone: same stroke, full ink at 2px so it reads at arm's length */
@media not all and (min-width:860px) and (min-aspect-ratio:1/1) {
  .where > span { background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 6' preserveAspectRatio='none'%3E%3Cpath d='M1 3.6C30 2.2 62 4.6 101 3.3S170 2.4 199 3.9' fill='none' stroke='%238f1d22' stroke-width='2' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E"); }
}
.where svg { display:inline-block; vertical-align:-2px; }
.where .pinico { width:16px; height:16px; margin-right:4px; }
.where .ext { width:13px; height:13px; margin-left:4px; opacity:.8; }
a.maplink { cursor:pointer; }
.count .pre { display:block; font-size:19px; letter-spacing:.14em; margin-bottom:8px; }
.count .pre:empty { display:none; }
.count { margin:30px 0 4px; line-height:1; }
.count b { display:block; font-weight:500; font-style:italic; font-size:clamp(64px,7vw,92px); letter-spacing:.01em; font-variant-numeric:lining-nums; }
.count span { display:block; font-size:19px; letter-spacing:.14em; text-transform:uppercase; margin-top:8px; }
/* phone: ♥ days to go ♥, the card's own SAVE THE DATE hearts (desktop has the floating panel hearts instead) */
@media not all and (min-width:860px) and (min-aspect-ratio:1/1) {
  #daysLabel::before, #daysLabel::after { content:''; display:inline-block; width:15px; height:17px; vertical-align:-1px; margin-right:14px;
    background:url(assets/sdheartL.webp) center/contain no-repeat; }
  #daysLabel::after { background-image:url(assets/sdheartR.webp); margin:0 0 0 10px; }   /* letter-spacing already trails the last letter */
}
/* the card's own drawn divider. Phone: 110px (the asset's 208px at 2x), card scale was too small to notice there.
   Desktop: the card's scale (416 of 4000 units) so the stroke weight matches; card width mirrors .card's sizing */
.rule { width:110px; aspect-ratio:208/20; margin:28px auto; border:0; background:url(assets/divider.webp) center/100% 100% no-repeat; }
@media (min-width:860px) and (min-aspect-ratio:1/1) { .rule { --cardW:min(100svh - 48px, 1100px) * 2 / 3; width:max(48px, var(--cardW) * .104); } }
.cal-title { font-size:15px; letter-spacing:.16em; text-transform:uppercase; margin:0 0 12px; }
.cal { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; }
/* drawn pill: border + fill live on ::before so only they wobble (filter), never the label */
.btn { position:relative; isolation:isolate; display:inline-flex; align-items:center; font:500 17px/1 var(--font); color:var(--ink); text-decoration:none; padding:12px 18px; border-radius:999px; transition:color .2s; }
.btn::before { content:''; position:absolute; inset:0; z-index:-1; border:1.5px solid rgba(143,29,34,.7);   /* 1.5px + gentle displacement: no torn dashes at 1x */ border-radius:inherit; background:rgba(255,255,255,.4);
               filter:url(#wobble); transition:background .2s; }
.btn:hover, .btn:focus-visible { color:var(--page); }
.btn:hover::before, .btn:focus-visible::before { background:var(--ink); }
.btn .calico { width:16px; height:16px; margin-right:8px; flex:none; }   /* currentColor: the logo inverts with the text on hover */
/* phone: a drawn outline instead (pen goes round twice and overshoots where it closes), 9-sliced so the round ends keep their shape;
   Safari renders the #wobble filter at 1x, so on phones it read as stepped dashes, not a pen line */
@media not all and (min-width:860px) and (min-aspect-ratio:1/1) {
  .btn { padding:13px 20px; }
  .btn::before { border:0 solid transparent; border-radius:0; background:none; filter:none;
    border-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='44' viewBox='0 0 120 44'%3E%3Cpath d='M25 3.4C50 2.5 74 3.9 96 3.0C110 2.6 118.4 11.2 118.2 22.2C118 33.6 109.6 41.3 96.4 41.1C72 40.5 48 41.7 23.8 41.0C10.6 40.7 2.0 32.6 2.2 21.8C2.4 10.8 11.6 3.6 28 3.1' fill='rgba(255,255,255,.55)' stroke='%238f1d22' stroke-width='1.6' stroke-linecap='round'/%3E%3Cpath d='M31 5.2C55 4.0 79 5.1 97.5 4.6C109.6 4.6 116.4 12.8 116.6 23.0C116.8 33.0 108.8 39.6 97.4 39.8C73 40.2 47 39.6 24.4 39.4C12.4 39.2 4.4 32.0 4.0 22.6C3.6 12.6 10.2 6.0 22 5.0' fill='none' stroke='%238f1d22' stroke-opacity='.5' stroke-width='1' stroke-linecap='round'/%3E%3C/svg%3E") 22 28 / 50% 26px stretch; }
  .btn:hover::before, .btn:focus-visible::before { background:none; border-image-source:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='44' viewBox='0 0 120 44'%3E%3Cpath d='M25 3.4C50 2.5 74 3.9 96 3.0C110 2.6 118.4 11.2 118.2 22.2C118 33.6 109.6 41.3 96.4 41.1C72 40.5 48 41.7 23.8 41.0C10.6 40.7 2.0 32.6 2.2 21.8C2.4 10.8 11.6 3.6 28 3.1' fill='%238f1d22' stroke='%238f1d22' stroke-width='1.6' stroke-linecap='round'/%3E%3Cpath d='M31 5.2C55 4.0 79 5.1 97.5 4.6C109.6 4.6 116.4 12.8 116.6 23.0C116.8 33.0 108.8 39.6 97.4 39.8C73 40.2 47 39.6 24.4 39.4C12.4 39.2 4.4 32.0 4.0 22.6C3.6 12.6 10.2 6.0 22 5.0' fill='none' stroke='%238f1d22' stroke-opacity='.9' stroke-width='1' stroke-linecap='round'/%3E%3C/svg%3E"); }
}
.invite { font-style:italic; font-size:clamp(26px,2.8vw,34px); line-height:1.25; white-space:pre-line; margin:0 0 22px; }
.invite:empty { display:none; }
.more { font-style:italic; font-size:clamp(18px,2vw,21px); margin:30px 0 0; }
.lang { margin-top:26px; display:flex; gap:6px; justify-content:center; font-size:16px; }
.lang button { font:inherit; color:inherit; background:none; border:0; padding:6px 8px; cursor:pointer; opacity:.8; border-bottom:1px solid transparent; }   /* .8 keeps inactive languages ≥ 4.5:1 */
.lang button[aria-pressed="true"] { opacity:1; border-bottom-color:currentColor; }
.lang button:hover, .lang button:focus-visible { opacity:1; }
.lang .flag { width:18px; height:13.5px; margin-right:6px; vertical-align:-1px; border-radius:2px; box-shadow:0 0 0 .5px rgba(0,0,0,.25); }   /* hairline keeps Georgia's white field off the paper */
.lang [lang=ka] { font-weight:300; }   /* EN/TR pages: light Noto Sans "ქართული" matches Cormorant's thin strokes */
:lang(ka) :is(.invite,.when,.whereline,.count .pre,.count span,.cal-title,.more,.hint,.lang [lang=ka]) { font-family:'Georgian Pen',var(--font); }
:lang(ka) .count span, :lang(ka) .cal-title { letter-spacing:.04em; }
:lang(ka) :is(.count span, .cal-title, .hint) { text-transform:none; }   /* Chrome garbles Georgian under uppercase; JS writes Mtavruli capitals instead (KA_CAPS) */
:lang(ka) .when, :lang(ka) .more, :lang(ka) .invite { font-style:normal; }   /* the Georgian face has no italic; avoid a fake slant */
/* this face's descenders (დ, ფ) hang ~.5em below the baseline, twice what its metrics declare; the floating "more" line is its own
   layer on iOS, clipped at its box, so the box is stretched to cover them (the negative margin keeps the layout where it was) */
:lang(ka) .more { padding-bottom:.3em; margin-bottom:-.3em; text-wrap:balance; }
/* one line: sized from the panel's own width (cqi), which also covers a squarish desktop window where the panel squeezes below 340px.
   The invite is ~13.1em wide in this face, the date ~11.9em, so these divisors leave some air; the vw line is the fallback for browsers without container units */
:lang(ka) .panel { container-type:inline-size; }
:lang(ka) .invite { font-size:min(26px, (100vw - 24px) / 15.6); font-size:min(26px, 100cqi / 15.6); }
@media (min-width:860px) and (min-aspect-ratio:1/1) { :lang(ka) .when { font-size:min(clamp(20px,2.2vw,26px), 100cqi / 14.2); } }
/* venue: "… · თბილისი" on one line where the panel is wide enough, else "…" / "თბილისი, საქართველო" on two (pieces built in app.js) */
.where .v-sep { display:none; }
@container (min-width:336px) { .where :is(br, .v-country) { display:none; } .where .v-sep { display:inline; } }

/* ---------- desktop with a mouse: the card tilts up to 4° toward the cursor, shadow shifts the other way (vars set in app.js) ---------- */
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference) and (min-width:860px) and (min-aspect-ratio:1/1) {
  .card { transform:perspective(1200px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition:transform .25s ease-out, box-shadow .25s ease-out;
          box-shadow:0 1px 2px rgba(80,30,20,.08), var(--sx, 0px) calc(18px + var(--sy, 0px)) 50px -20px rgba(80,30,20,.35); }
}

/* ---------- desktop: the card's illustration leaks onto the page (faint leaves in the corners, small hearts around the panel) ---------- */
.leaks, .ph { display:none; }
@media (min-width:860px) and (min-aspect-ratio:1/1) {
  .leaks { display:block; position:fixed; inset:0; z-index:-1; pointer-events:none; overflow:hidden; }
  .leaks img { position:absolute; opacity:.18; }
  .leakL { left:-40px; bottom:-70px; width:clamp(200px,20vw,320px); transform:rotate(-8deg); }
  .leakR { right:-50px; top:-60px; width:clamp(200px,20vw,320px); transform:rotate(172deg); }
  .panel { position:relative; }
  .ph { display:block; position:absolute; opacity:.4; pointer-events:none; }
  .ph1 { width:18px; left:-6px; top:2%; transform:rotate(-14deg); }
  :lang(ka) .ph1 { left:-30px; }   /* the one-line Georgian invite spans the full panel width */
  .ph2 { width:15px; right:-2px; top:34%; transform:rotate(10deg); }
  .ph3 { width:17px; left:4px; bottom:4%; transform:rotate(8deg); }
}

/* mobile: "details below" cue, in the flow between card and panel (never overlaps text) */
.hint { display:flex; flex-direction:column; align-items:center; gap:2px; margin-top:8px; padding:6px 16px; color:var(--ink); text-decoration:none;
        font-size:14px; letter-spacing:.16em; text-transform:uppercase; opacity:0; }
.hint + .panel { margin-top:16px; }
.hint svg { width:18px; height:18px; }
:lang(ka) .hint { letter-spacing:.04em; }
.on .hint { animation:fade 1.2s ease-out calc(var(--namesEnd, 6s) + 2.4s) forwards; }
.on .hint svg { animation:bob 2.4s ease-in-out calc(var(--namesEnd, 6s) + 3.6s) infinite; }
@keyframes bob { 0%,100% { transform:none; } 50% { transform:translateY(4px); } }
@media (min-width:860px) and (min-aspect-ratio:1/1) { .hint { display:none; } }   /* desktop shows everything on one screen */

/* wax-seal replay: in the flow under the panel on phone, fixed bottom-right on desktop */
.replay { display:block; width:44px; height:44px; padding:0; margin-top:28px; border:0; border-radius:50%; background:none; cursor:pointer;
          filter:drop-shadow(0 2px 2px rgba(80,30,20,.28)); transition:transform .25s ease-out; }
.replay:hover { transform:rotate(-10deg) scale(1.05); }
@media (min-width:860px) and (min-aspect-ratio:1/1) {
  .replay { position:fixed; right:calc(18px + env(safe-area-inset-right,0px)); bottom:calc(18px + env(safe-area-inset-bottom,0px)); margin:0; }
}

svg { display:block; width:100%; height:100%; }
svg.defs { position:absolute; width:0; height:0; overflow:hidden; }
svg g { transform-box:view-box; }

/* ---------- intro (plays once) ---------- */
.paper,.heart,.pin,.place,.names,.namesfull,.rise,.sdh,.divider { opacity:0; }
.on .paper { animation:fade 1.4s ease-out forwards; }
.on .pin { animation:pindrop 1s cubic-bezier(.3,.7,.4,1) 1.0s forwards; }
.on .place { animation:riseIn 1s ease-out 1.5s forwards; }
.on .names { opacity:1; transition:none; }
.on .namesfull { animation:fade .5s ease-out forwards; animation-delay:var(--namesEnd, 6s); }
.on .h1 { animation:pop .7s cubic-bezier(.3,1.6,.5,1) calc(var(--namesEnd, 6s) + .1s) forwards, float1 4.2s ease-in-out calc(var(--namesEnd, 6s) + .8s) infinite; }
.on .h2 { animation:pop .7s cubic-bezier(.3,1.6,.5,1) calc(var(--namesEnd, 6s) + .35s) forwards, float2 3.7s ease-in-out calc(var(--namesEnd, 6s) + 1.05s) infinite; }
.on .h3 { animation:pop .7s cubic-bezier(.3,1.6,.5,1) calc(var(--namesEnd, 6s) + .6s) forwards, float3 4.6s ease-in-out calc(var(--namesEnd, 6s) + 1.3s) infinite; }
.on .sdt { animation:riseIn 1.1s ease-out calc(var(--namesEnd, 6s) + .7s) forwards; }
.on .sdhL { animation:pop .6s ease-out calc(var(--namesEnd, 6s) + 1.1s) forwards, beat 2.6s ease-in-out calc(var(--namesEnd, 6s) + 2s) infinite; }
.on .sdhR { animation:pop .6s ease-out calc(var(--namesEnd, 6s) + 1.2s) forwards, beat 2.6s ease-in-out calc(var(--namesEnd, 6s) + 2.15s) infinite; }
.on .divider { animation:draw .9s ease-out calc(var(--namesEnd, 6s) + 1.2s) forwards; }
.on .date { animation:riseIn 1.1s ease-out calc(var(--namesEnd, 6s) + 1.5s) forwards; }
.on .panel { animation:fade 1.2s ease-out calc(var(--namesEnd, 6s) + 2.4s) forwards; }

@keyframes fade { to { opacity:1; } }
@keyframes riseIn { from { opacity:0; transform:translateY(60px); } to { opacity:1; transform:none; } }
@keyframes pindrop { 0% { opacity:0; transform:translateY(-260px); } 35% { opacity:1; }
  55% { transform:translateY(0) scale(1.06,.9); } 70% { transform:translateY(-55px) scale(.97,1.04); }
  85% { transform:translateY(0) scale(1.03,.96); } 93% { transform:translateY(-12px); } 100% { opacity:1; transform:none; } }
@keyframes pop { 0% { opacity:0; transform:scale(.3); } 100% { opacity:1; transform:scale(1); } }
@keyframes draw { from { opacity:1; transform:scaleX(0); } to { opacity:1; transform:scaleX(1); } }

/* ---------- gentle float on the texts once they have landed (names stay still) ---------- */
.on .flA { animation:hover1 6.2s ease-in-out 2.6s infinite; }
.on .flB { animation:hover2 5.6s ease-in-out calc(var(--namesEnd, 6s) + 2.2s) infinite; }
.on .flC { animation:hover3 6.8s ease-in-out calc(var(--namesEnd, 6s) + 2.4s) infinite; }
.on .flD { animation:hover1 5.9s ease-in-out calc(var(--namesEnd, 6s) + 2.9s) infinite; }
.on .more { animation:hoverPx 6.4s ease-in-out calc(var(--namesEnd, 6s) + 3.8s) infinite; }
@keyframes hover1 { 0%,100% { transform:none; } 50% { transform:translateY(-34px) rotate(.35deg); } }
@keyframes hover2 { 0%,100% { transform:none; } 50% { transform:translateY(-28px) rotate(-.3deg); } }
@keyframes hover3 { 0%,100% { transform:none; } 50% { transform:translateY(-22px); } }
@keyframes hoverPx { 0%,100% { transform:none; } 50% { transform:translateY(-3px); } }

/* ---------- ambient loops ---------- */
.on .cloud1 { animation:drift 16s linear -2s infinite; }
.on .cloud2 { animation:drift 19s linear -9s infinite; }
.on .cloud3 { animation:drift 15s linear -5s infinite; }
.on .cloud4 { animation:drift 17s linear -13s infinite; }
.on .cloud5 { animation:drift 18s linear -7s infinite; }
@keyframes drift { 0% { opacity:0; transform:translateX(-140px); } 18% { opacity:1; } 70% { opacity:1; } 100% { opacity:0; transform:translateX(260px); } }

.on .light { animation:blink 2.4s steps(1,end) infinite; }
.light { opacity:0; }
@keyframes blink { 0% { opacity:1; } 18% { opacity:0; } 100% { opacity:0; } }

/* leaves: half the old speed, softer gusts */
.on .leafL { animation:windL 13s ease-in-out infinite; }
.on .leafR { animation:windR 14.5s ease-in-out -4.6s infinite; }
@keyframes windL { 0%,100% { transform:rotate(-1.5deg); } 28% { transform:rotate(3.5deg) skewX(-2deg); } 50% { transform:rotate(.5deg); } 74% { transform:rotate(4deg) skewX(-2.5deg); } }
@keyframes windR { 0%,100% { transform:rotate(1.5deg); } 26% { transform:rotate(-3.5deg) skewX(2deg); } 52% { transform:rotate(-.5deg); } 76% { transform:rotate(-4deg) skewX(2.5deg); } }

.on .man { animation:man 6.9s ease-in-out 1.2s infinite; }
@keyframes man { 0%,100% { transform:rotate(1.5deg); } 50% { transform:rotate(-5deg); } }
@keyframes gb0{0%,100%{transform:rotate(-0.000deg)}50%{transform:rotate(0.000deg)}}
.on .gb0{animation:gb0 6.5s ease-in-out 0.4s infinite}
@keyframes gb1{0%,100%{transform:rotate(-0.292deg)}50%{transform:rotate(0.833deg)}}
.on .gb1{animation:gb1 6.5s ease-in-out 0.4s infinite}
@keyframes gb2{0%,100%{transform:rotate(-0.583deg)}50%{transform:rotate(1.667deg)}}
.on .gb2{animation:gb2 6.5s ease-in-out 0.4s infinite}
@keyframes gb3{0%,100%{transform:rotate(-0.875deg)}50%{transform:rotate(2.500deg)}}
.on .gb3{animation:gb3 6.5s ease-in-out 0.4s infinite}
@keyframes gb4{0%,100%{transform:rotate(-1.167deg)}50%{transform:rotate(3.333deg)}}
.on .gb4{animation:gb4 6.5s ease-in-out 0.4s infinite}
@keyframes gb5{0%,100%{transform:rotate(-1.458deg)}50%{transform:rotate(4.167deg)}}
.on .gb5{animation:gb5 6.5s ease-in-out 0.4s infinite}
@keyframes gb6{0%,100%{transform:rotate(-1.750deg)}50%{transform:rotate(5.000deg)}}
.on .gb6{animation:gb6 6.5s ease-in-out 0.4s infinite}

/* dog: same slow sway as the couple, no hop or head-shake */
.on .dog { animation:dog 7.4s ease-in-out .8s infinite; }
@keyframes dog { 0%,100% { transform:rotate(1.5deg); } 50% { transform:rotate(-3.5deg); } }

@keyframes float1 { 0%,100% { opacity:1; transform:translateY(0) rotate(-4deg); } 50% { opacity:1; transform:translateY(-55px) rotate(5deg) scale(1.06); } }
@keyframes float2 { 0%,100% { opacity:1; transform:translateY(0) rotate(3deg); } 50% { opacity:1; transform:translateY(-45px) rotate(-5deg) scale(1.08); } }
@keyframes float3 { 0%,100% { opacity:1; transform:translateY(0) rotate(-3deg); } 50% { opacity:1; transform:translateY(-60px) rotate(6deg) scale(1.05); } }
@keyframes beat { 0%,100% { opacity:1; transform:scale(1); } 12% { opacity:1; transform:scale(1.18); } 24% { opacity:1; transform:scale(1); } 34% { opacity:1; transform:scale(1.12); } 46% { opacity:1; transform:scale(1); } }

/* reduced motion: show the finished page, no movement */
@media (prefers-reduced-motion: reduce) {
  .card *, .panel, .more, .hint, .hint svg, .where > span { animation:none !important; }
  .paper,.heart,.pin,.place,.namesfull,.rise,.sdh,.divider,.panel,.hint { opacity:1 !important; }
  .names { opacity:0 !important; }
  .replay { display:none; }   /* nothing to replay: the finished card is shown */
}

/* phone: a garland crowns the panel, two branches meeting under a heart, like the branches beside the couple */
@media not all and (min-width:860px) and (min-aspect-ratio:1/1) {
  .panel { position:relative; padding-top:88px; }
  .panel::before, .panel::after { content:''; position:absolute; top:0; width:80px; height:74px; pointer-events:none;
                                  background:url(assets/leafL.webp) center/contain no-repeat; }
  .panel::before { right:calc(50% + 8px); transform:rotate(-62deg); }
  .panel::after { left:calc(50% + 14px); background-image:url(assets/leafR.webp); transform:rotate(62deg); }
  .ph2 { display:block; position:absolute; width:20px; left:calc(50% - 10px); top:14px; pointer-events:none; }
  .replay { margin-top:30px; }
}
