/* ─────────────────────────────────────────────────────────────
   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);
  --page-top:clamp(.75rem,2svh,1.25rem);
  --page-bottom:clamp(1rem,3svh,2rem);

  --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 page stays in normal document flow. The button owns the card state;
   scrolling is never used as an animation timeline. */

.stage{ min-height:100dvh; }

.stage__inner{
  min-height:100dvh;
  display:flex; flex-direction:column;
  align-items:center; justify-content:flex-start;
  padding:var(--page-top) 1rem var(--page-bottom);
  perspective:2200px;
}

.card3d{
  position:relative;
  width:var(--card-w);
  aspect-ratio:724 / 1086;
  flex:none;
  transform-style:preserve-3d;
  transform:rotateY(0deg);
  will-change:transform;
}
.card3d[data-flipped="true"]{ transform:rotateY(180deg); }

.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%; }

/* An invisible, full-bottle-sized button keeps the traced artwork untouched
   while giving touch and keyboard users a generous replay target. */
.bottle-trigger{
  position:absolute;
  left:85.1%; top:43.8%;
  width:18cqw; aspect-ratio:440 / 1008;
  z-index:3;
  padding:0; border:0;
  transform:translate(-50%,-50%);
  background:transparent;
  cursor:pointer; touch-action:manipulation;
  -webkit-tap-highlight-color:transparent;
}

/* ── 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;
  margin-top:clamp(1rem,3svh,2rem);
  letter-spacing:.22em; text-indent:.22em; text-transform:uppercase;
  transition:color .25s;
  --chev:0deg;
}
.cue:hover{ color:var(--ink); }
.cue svg{ width:1.3rem; height:1.3rem; flex:none;
          transform:rotate(var(--chev)); }
.cue[data-flipped="true"]{ --chev:180deg; --nudgeY:-3px; }

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

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

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

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

  .card3d{ transition:transform .8s cubic-bezier(.65,0,.35,1); }

  /* 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); }
  }

  /* A tap puts the cork back immediately, pauses for one small beat, then
     pops it again. Distinct keyframe names ensure this animation starts over
     rather than resuming the page-load animation. */
  .card--front.is-replaying-bottle .doodle--cork{
    animation:corkReplay 1s cubic-bezier(.22,.66,.36,1) .35s both;
  }
  @keyframes corkReplay{
    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.is-replaying-bottle .doodle--sparkle,
  .card--front.is-replaying-bottle .doodle--sparkle2{
    animation:burstReplay .5s cubic-bezier(.2,.9,.3,1) .37s both;
  }
  @keyframes burstReplay{
    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){
  .stage__inner{
    min-height:auto; perspective:none;
    padding-top:max(var(--page-top), clamp(2rem,6svh,4rem));
    padding-bottom:max(var(--page-bottom), 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, .bottle-trigger{ 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{
  width:var(--card-w);
  min-height:2rem;
  display:flex; justify-content:flex-end; gap:.1rem;
  direction:ltr;
  flex:none;
}
.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)); }
}
