/* ─────────────────────────────────────────────────────────────
   Sophie & Ron — save the date
   Palette and card proportions sampled from the printed card.
   The site is one object: a card you turn over.
   ───────────────────────────────────────────────────────────── */

:root{
  --paper:     #FBF6F2;   /* the card stock */
  --ink:       #123287;   /* the pen */
  --ink-deep:  #0A1F5C;   /* pressed harder */
  --ink-soft:  #8494C0;   /* secondary text */
  --wash:      #F1E9E1;   /* the surface the card rests on */
  --edge:      rgba(18,50,135,.14);
  --safe-top:  env(safe-area-inset-top, 0px);

  --card-w: min(92vw, calc(80svh * 724 / 1086), 600px);
  --step: clamp(.9rem, .55rem + .9vw, 1.15rem);
}

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

body{
  margin:0;
  background:var(--wash);
  color:var(--ink);
  font-family:"Jost", "Heebo", ui-sans-serif, system-ui, sans-serif;
  font-size:var(--step);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

.sprite{ position:absolute; width:0; height:0; overflow:hidden; }

/* ── The turn ──────────────────────────────────────────────
   The section is tall; the card sticks inside it, and how far
   you have scrolled through it is how far the card has turned. */

.flipzone{ position:relative; height:220svh; }

.flipzone__sticky{
  position:sticky; top:0;
  height:100svh;
  display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  gap:clamp(1rem,3svh,2rem);
  padding:clamp(1rem,4svh,2.5rem) 1rem;
  perspective:2200px;
}

.card3d{
  position:relative;
  width:var(--card-w);
  aspect-ratio:724 / 1086;
  transform-style:preserve-3d;
  /* Keep the card below iOS's status / "Back to Messages" area. */
  transform:
    translateY(var(--safe-top))
    rotateY(calc(var(--flip,0) * 180deg));
  will-change:transform;
}

.card{
  position:absolute; inset:0;
  container-type:size;
  background:var(--paper);
  backface-visibility:hidden;
  -webkit-backface-visibility:hidden;
  box-shadow:
    0 1px 1px rgba(60,40,25,.05),
    0 8px 22px -8px rgba(60,40,25,.14),
    0 28px 60px -30px rgba(60,40,25,.28);
}
.card--back{ transform:rotateY(180deg); }

/* The face turned away is hidden outright, not just back-face culled — see
   the note in app.js. The swap happens at the halfway point, where the card
   is edge-on and therefore invisible, so it cannot be seen happening. */
.card3d[data-face="back"]  .card--front{ visibility:hidden; }
.card3d[data-face="front"] .card--back { visibility:hidden; }

/* paper tooth */
.card__grain{
  position:absolute; inset:0; pointer-events:none; z-index:2;
  opacity:.3;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.28'/%3E%3C/svg%3E");
}

/* ── The drawn elements ────────────────────────────────────── */

.card__art{ position:absolute; inset:0; }

.doodle{
  position:absolute;
  height:auto;
  color:var(--ink);
  transform:translate(-50%,-50%);
  overflow:visible;
}

/* front — widths as measured on the printed card, positions nudged
   to follow the vertically centred text block. */
.doodle--wine     { left:15.6%; top:34.0%; width:12.4%; }
.doodle--bottle   { left:85.1%; top:43.8%; width:15.2%; }
.doodle--cork     { left:89.9%; top:33.5%; width: 5.0%; }
.doodle--sparkle  { left:91.0%; top:30.6%; width: 9.9%; }
.doodle--sparkle2 { left:94.6%; top:33.7%; width: 3.9%; }
.doodle--cake     { left:15.0%; top:81.0%; width:22.0%; }
.doodle--flute    { left:87.5%; top:82.0%; width: 9.9%; }
.doodle--heart-tl { left:20.0%; top:10.0%; width: 6.4%; }
.doodle--heart-sm { left:87.4%; top:23.0%; width: 4.6%; }
.doodle--heart-l  { left:13.4%; top:55.0%; width: 4.3%; }
.doodle--heart-b  { left:54.6%; top:89.0%; width: 3.9%; }
.doodle--heart-vb { left:52.3%; top:96.0%; width: 3.3%; }

/* ── The rule, used on both faces ──────────────────────────── */

.rule{
  display:flex; align-items:center; justify-content:center;
  gap:3.2cqw;
}
.rule__line{ flex:1; height:.42cqw; background:var(--ink); border-radius:1px; }
.rule__heart{ width:4.3cqw; height:auto; color:var(--ink); flex:none; }

/* ── Front ─────────────────────────────────────────────────── */

.card__text{
  position:absolute; inset:0; z-index:1;
  display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  padding:6cqh 6cqw;
  text-align:center;
}
.card__text > *{ margin:0; white-space:nowrap; }

.lockup{ line-height:0; }
.lockup__art{ height:37.8cqh; width:auto; color:var(--ink); display:block; }

/* gaps keep the proportions the printed card had between these three */
.names{
  margin-top:7cqh;
  font-size:6.7cqw; font-weight:400;
  letter-spacing:.13em; text-indent:.13em;
  text-transform:uppercase; line-height:1;
  direction:ltr;
}
.names .amp{ letter-spacing:.05em; }

.card__text .rule{ margin-top:3.2cqh; width:52cqw; }

.date{
  margin-top:4.2cqh;
  font-size:7.0cqw; font-weight:400;
  letter-spacing:.13em; text-indent:.13em;
  line-height:1; font-variant-numeric:lining-nums;
  direction:ltr;
}

.place{
  margin-top:3.8cqh;
  font-size:3.0cqw; font-weight:400;
  letter-spacing:.30em; text-indent:.30em;
  text-transform:uppercase; line-height:1;
}

/* ── Back ──────────────────────────────────────────────────── */

.back{
  position:absolute; inset:0; z-index:1;
  display:flex; flex-direction:column;
  align-items:center; justify-content:center;
  padding:7cqh 10cqw;
  text-align:center;
}

/* The date and the place are the reason this side exists. */
/* The front's "SAVE the DATE" is traced artwork, not a typeface, and it
   holds no digits — so the date is set in the nearest brush face instead
   of the clean sans, to echo it. Brush letterforms carry their own
   rhythm, so the wide tracking of the sans comes off. */
.back__date{
  margin:0;
  font-family:"Permanent Marker", "Heebo", ui-rounded, cursive;
  font-size:10cqw; font-weight:400;
  letter-spacing:.02em; text-indent:.02em;
  line-height:1.05;
  direction:ltr;
}

.back__place{
  margin:2.8cqh 0 0;
  font-size:3.0cqw; font-weight:400;
  letter-spacing:.30em; text-indent:.30em;
  text-transform:uppercase; line-height:1.3;
}

.back .rule{ width:42cqw; margin:4.6cqh 0 0; }

/* The number and its unit carry the brush face; the line beneath is set
   like the day-and-city line above it. */
.back__count{ margin:4.4cqh 0 0; }

.back__count-lead{
  display:block;
  font-family:"Permanent Marker", "Heebo", ui-rounded, cursive;
  font-size:5.2cqw; font-weight:400;
  letter-spacing:0; line-height:1.15;
  color:var(--ink);
}

.back__count-tail{
  display:block;
  margin-top:1.5cqh;
  font-size:2.9cqw; font-weight:400;
  letter-spacing:.26em; text-indent:.26em;
  text-transform:uppercase; line-height:1.2;
  color:var(--ink-soft);
}

.back__actions{
  margin:5.4cqh 0 0;
  display:flex; flex-direction:column; align-items:center; gap:1.8cqh;
}

.btn{
  appearance:none;
  padding:1.9cqh 5cqw;
  font:inherit; font-size:2.9cqw;
  letter-spacing:.16em; text-indent:.16em; text-transform:uppercase;
  color:var(--paper); background:var(--ink);
  border:1.5px solid var(--ink); border-radius:0;
  cursor:pointer;
  transition:background .2s, border-color .2s, transform .12s;
}
.btn:hover{ background:var(--ink-deep); border-color:var(--ink-deep); }
.btn:active{ transform:translateY(1px); }

.link{
  font-size:2.7cqw; color:var(--ink-soft);
  text-decoration:none; border-bottom:1px solid transparent;
  transition:color .2s, border-color .2s;
}
.link:hover{ color:var(--ink); border-bottom-color:var(--ink); }

/* The warm line leads; the practical one sits quietly under it. */
.back__note{
  margin:5.2cqh 0 0;
  font-size:5.2cqw; font-weight:400;
  line-height:1.3;
  color:var(--ink);
}

.back__closing{
  margin:2.2cqh 0 0;
  font-size:4.6cqw; font-weight:400;
  line-height:1.3;
  color:var(--ink-soft);
}

/* ── The turn-it-over control ──────────────────────────────
   Everything that matters is already on the front, so this is an
   invitation to look further, not the way in. */

.cue{
  appearance:none; background:none; border:0;
  display:inline-flex; flex-direction:column; align-items:center; gap:.15rem;
  padding:.3rem .5rem;
  color:var(--ink); cursor:pointer;
  font:inherit; font-size:.72rem;
  letter-spacing:.22em; text-indent:.22em; text-transform:uppercase;
  transform:translateY(var(--safe-top));
  transition:color .25s;
}
.cue:hover{ color:var(--ink); }
.cue svg{ width:1.3rem; height:1.3rem; flex:none;
          /* --chev is written every frame from the card's own turn
             progress, so no transition: it is already continuous. */
          transform:rotate(var(--chev,0deg)); }
.cue[data-flipped="true"]{ --nudgeY:-3px; }   /* nudge upward once turned */

/* ── Focus ─────────────────────────────────────────────────── */

:focus-visible{ outline:2px solid var(--ink); outline-offset:3px; }

/* ── The card draws itself on ──────────────────────────────── */

@media (prefers-reduced-motion:no-preference){

  /* Illustrations and copy arrive together, on one beat — same delay,
     same duration, same curve. */
  .card--front .doodle,
  .names, .card__text .rule, .date, .place{
    opacity:0;
    animation-duration:1.1s;
    animation-timing-function:cubic-bezier(.22,.61,.36,1);
    animation-delay:.35s;
    animation-fill-mode:both;
  }
  .card--front .doodle{ animation-name:riseD; }
  .names, .card__text .rule, .date, .place{ animation-name:rise; }

  @keyframes riseD{
    from{ opacity:0; transform:translate(-50%, calc(-50% + 9px)); }
    to  { opacity:1; transform:translate(-50%,-50%); }
  }
  @keyframes rise{
    from{ opacity:0; transform:translateY(9px); }
    to  { opacity:1; transform:translateY(0); }
  }

  /* The lettering is the anchor — it is there from the first paint. */

  /* Keep the flip affordance visible from first paint; only its chevron
     waits for the card's entrance before it starts nudging. */
  .cue svg{ animation:nudge 2.2s ease-in-out 3.2s infinite; }
  @keyframes nudge{
    0%,100%{ transform:translateY(0) rotate(var(--chev,0deg)); }
    50%    { transform:translateY(var(--nudgeY,3px)) rotate(var(--chev,0deg)); }
  }

  /* Once the card has settled, the cork leaves the bottle: up, away and
     spinning, while the rays burst out of the neck. `forwards` (not `both`)
     matters — a backwards fill would override its own entrance. */
  .card--front .doodle--cork{
    animation:
      riseD 1.1s cubic-bezier(.22,.61,.36,1) .35s both,
      cork 1s cubic-bezier(.22,.66,.36,1) 1.65s forwards;
  }
  @keyframes cork{
    0%  { opacity:1; transform:translate(-50%,-50%) rotate(0deg); }
    55% { opacity:1; }
    100%{ opacity:0;
          transform:translate(calc(-50% + 7cqw), calc(-50% - 14cqh)) rotate(215deg); }
  }

  .card--front .doodle--sparkle,
  .card--front .doodle--sparkle2{
    opacity:0;
    transform-origin:12% 96%;
    animation:burst .5s cubic-bezier(.2,.9,.3,1) 1.67s both;
  }
  @keyframes burst{
    0%  { opacity:0; transform:translate(-50%,-50%) scale(.25); }
    60% { opacity:1; transform:translate(-50%,-50%) scale(1.2); }
    100%{ opacity:1; transform:translate(-50%,-50%) scale(1); }
  }

  /* the hearts keep a slow pulse, like the hand never quite left */
  .card--front .doodle--heart-tl, .card--front .doodle--heart-sm,
  .card--front .doodle--heart-l,  .card--front .doodle--heart-b,
  .card--front .doodle--heart-vb{
    animation:
      riseD 1.1s cubic-bezier(.22,.61,.36,1) .35s both,
      float 7s ease-in-out 2.6s infinite;
  }
  @keyframes float{
    0%,100%{ transform:translate(-50%,-50%); }
    50%    { transform:translate(-50%,calc(-50% - 4px)); }
  }
}

/* No turning for anyone who asked for less motion — the two faces
   simply stack, and the whole page is readable by scrolling. */
@media (prefers-reduced-motion:reduce){
  .flipzone{ height:auto; }
  .flipzone__sticky{
    position:static; height:auto; perspective:none;
    padding-block:clamp(2rem,6svh,4rem);
    padding-top:calc(var(--safe-top) + clamp(2rem,6svh,4rem));
  }
  .card3d{
    transform:none; transform-style:flat;
    aspect-ratio:auto; height:auto;
    display:flex; flex-direction:column; gap:clamp(1.5rem,4vh,2.5rem);
  }
  .card{
    position:relative; inset:auto;
    aspect-ratio:724 / 1086;
    backface-visibility:visible; -webkit-backface-visibility:visible;
  }
  .card--back{ transform:none; }
  .cue{ display:none; }
  .card--back{ margin-top:0; }
}

/* Hebrew reads right-to-left, but its letterforms should not inherit the
   tracking and uppercase treatment used for the Latin translations. */
html[lang="he"] .names,
html[lang="he"] .names .amp,
html[lang="he"] .place,
html[lang="he"] .back__place,
html[lang="he"] .back__count-tail,
html[lang="he"] .btn,
html[lang="he"] .cue{
  letter-spacing:0;
  text-indent:0;
  text-transform:none;
}
html[lang="he"] .names{ direction:rtl; }

/* ── Language switcher ─────────────────────────────────────── */

.langs{
  position:fixed;
  top:calc(var(--safe-top) + clamp(.9rem,2.2vh,1.5rem));
  right:clamp(.9rem,2.2vw,1.6rem);
  z-index:10;
  display:flex; gap:.1rem;
  direction:ltr;
}
.langs button{
  appearance:none; background:none; border:0;
  padding:.4rem .5rem;
  font:inherit; font-size:.7rem;
  letter-spacing:.16em; text-indent:.16em;
  color:var(--ink-soft); cursor:pointer;
  transition:color .2s;
}
.langs button:hover{ color:var(--ink); }
.langs button[aria-pressed="true"]{
  color:var(--ink);
  box-shadow:inset 0 -1.5px 0 var(--ink);
}

/* ── Small screens ─────────────────────────────────────────── */

@media (max-width:520px){
  :root{ --card-w:min(94vw, calc(78svh * 724 / 1086)); }
}
