/* Mochi opening screen, loaded after styles.css. Everything here is scoped to the opening
   screen (.entry): the save-the-date spread underneath keeps its blush and red, unchanged.
   Card 9 of the record-scene palettes (2 November 2026), from refrence-images/Color Pallet.png:
   a sky-blue #5FA8C2 ground with everything drawn or written in crimson #7D2027 (3.7:1). It is
   the approved crimson-and-sky opening with its two colours remapped (tools/card9_opening.py):
   crimson ground -> sky blue, sky ink -> crimson, so the paper grain, the record and Mochi are
   strictly these two colours. The approved crimson version is in media/crimson/.
   Layout after the right-hand cards in the same reference: saturated ground, one ornament,
   small spaced capitals and a lot of air. */
.entry {
  --ground: #5FA8C2;             /* sky blue */
  --ink: #7D2027;                /* crimson */
  --blush: var(--ground);        /* inside the opening screen only */
  --red: var(--ink);

  /* Wells pressed into the paper: nearly square, with an
     understated bevel like an impression: a darker inner upper edge and a faint lighter inner
     lower edge. The well is the ground's own blue a touch lighter, which keeps the crimson
     typing readable (3.9:1). Focus and errors tint the edge crimson, like their message. */
  --well-blush: #5EACC6;
  --press-depth: inset 0 1.5px 1.5px -0.5px rgba(10, 40, 52, 0.5), inset 0 -1px 0 rgba(240, 250, 255, 0.1);
  --press: var(--press-depth), inset 0 0 0 1px rgba(10, 40, 52, 0.12);
  --press-focus: var(--press-depth), inset 0 0 0 1px rgba(125, 32, 39, 0.8);
  --press-error: var(--press-depth), inset 0 0 0 1.5px var(--ink);

  /* An even blue with only a fine paper grain (the approved crimson tile, remapped): the tile's
     mottling is removed and its tooth kept at about +-2 levels. */
  background: var(--ground) url("media/card9/paper-fine.webp?v=20261102a") center top / 680px auto repeat;
  /* Colour, space and one focal point. Heading, Mochi and form form one group, centred with a
     touch more room below than above (1 : 1.15). Under the heading, a gap of 14% of the screen
     height (72-120px). With the keyboard open the outer space gives way first. */
  padding-top: calc(env(safe-area-inset-top) + 24px);
}
.entry::before { content: ""; flex: 1 1 0; }
.entry::after { content: ""; flex: 1.15 1 0; }
.entry > .entry__header { margin-top: 0; }
.entry > .entry__form { margin-bottom: 0; }
.entry > .entry__image { margin-top: 0; }
.entry__space { flex: 0 0 auto; height: clamp(72px, 14svh, 120px); }

/* Heading: "Con todo nuestro amor" as lettering: CON7 (Type/con7.png), a fine handwritten pen,
   in crimson on a transparent ground (the words are its alt text). One line, kept 28px in
   from each side of the column (up to 18rem wide), so it has room to breathe.
   Below it, "With all our love": small typewriter capitals (Courier Prime, as in the form fields),
   18px under the title. */
/* What guests type into the name and phone fields: Courier Prime, a typewriter face, in natural
   capitalisation. SIL Open Font License (fonts/CourierPrime-OFL.txt). */
@font-face {
  font-family: "Courier Prime";
  src: url("fonts/courierprime-regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
.entry__header { flex: 0 0 auto; align-self: stretch; text-align: center; color: var(--ink); }
.entry__heading { margin: 0; }
.entry__heading img { display: block; width: min(calc(100% - 56px), 18rem); height: auto; margin: 0 auto; }
.entry__subheading { margin: 18px 0 0; padding-left: 0.24em; font: 400 0.75rem/1 "Courier Prime", "Courier New", Courier, monospace; letter-spacing: 0.24em; text-transform: uppercase; color: var(--ink); }

/* Mochi: his original drawing in crimson, filled with the ground's blue. The video is cropped to
   exactly the window this box shows and is transparent around him, so it fills the box and draws
   normally; the blue paper shows through. */
.entry .clip--mochi { width: calc(var(--art) * 0.58); }
.entry .clip--mochi video {
  width: 100%;
  height: 100%;
  margin: 0;
  aspect-ratio: 588 / 476;
  mix-blend-mode: normal;
  -webkit-mask-image: none;
  mask-image: none;
}

/* The form: compact capitals for labels, slim spacing, wells with nearly square corners. */
.entry__form { max-width: 17.5rem; margin-top: 24px; }
.entry__field { margin-bottom: 14px; }
.entry__field label { margin: 0 0 7px; padding-left: 1px; font: 400 0.625rem/1 var(--font-ui); letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink); }
.entry__form input[type="text"], .entry__form input[type="tel"], .entry__code { border-radius: 2px; }
/* The country code beside the number uses it too, so the whole phone field reads as one. */
.entry__form input[type="text"], .entry__form input[type="tel"], .entry__code {
  font-family: "Courier Prime", "Courier New", Courier, monospace;   /* stays 16px: phones don't zoom */
  color: var(--ink);
  caret-color: var(--ink);
}
.entry__phone { gap: 6px; }
.entry__form .form-error { color: var(--ink); border-left-color: var(--ink); }   /* two colours only */

/* CONTINUE: small and architectural, a fine crimson rectangle outline with crimson
   capitals. The button is 44px tall for the tap; the outline is drawn 7px inside it, so the
   visible rectangle is 134 x 30. It fills crimson while pressed; until the name and number
   are valid the outline and lettering are dimmed. */
.entry__continue {
  width: 148px;
  margin: 8px auto 0;
  padding: 0 0 0 0.22em;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font: 400 0.6875rem/1 var(--font-ui);
  letter-spacing: 0.22em;
  outline: 1px solid var(--ink);
  outline-offset: -7px;
}
.entry__continue:active:not([disabled]) { background: var(--ink) padding-box; color: var(--ground); }
.entry__continue:focus-visible { outline: 2px solid var(--ink); outline-offset: -7px; }
.entry__continue[disabled] { opacity: 0.5; }

/* After a valid Send: the form fades, a large record rises into the lower part of the
   screen while Mochi settles onto it, then it starts to turn as he starts walking, so he walks
   on it; then the whole screen fades to the save the date.
   After refrence-images/record_size.png: the record runs off the left, right and bottom edges
   and fills the lower ~45% of the screen; it is seen from a low angle (its depth is 0.51 of its
   width) and tilted 7 degrees, higher on the right, with its centre a little right of the middle.
   Mochi stands where the dancers stand, on the upper part of its surface (app.js measures where
   that is and sets --drop, how far he moves down to reach it).
   Only the disc turns, inside the fixed tilt (rotate + scaleY on .record), so the angle never
   changes. It turns anticlockwise so the surface under his feet moves backwards.
   --rec-d is the diameter: twice the screen width on a phone, capped on large screens. Its centre
   sits 0.23 diameters above the bottom of the screen, so the lowest point of the outline is
   always ~3% of the diameter below the bottom edge.
   Two colours only: the record is crimson with sky-blue grooves, label and spindle hole, the same
   pair as the screen, the heading and Mochi. */
.entry .clip--mochi { z-index: 1; }
.record-stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;            /* the record runs off the screen without making it scroll */
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(48px);
}
.record {
  --rec-d: min(200vw, 960px);
  --tilt: -7deg;
  --depth: 0.51;
  position: absolute;
  left: calc(55% - var(--rec-d) / 2);
  top: calc(100% - var(--rec-d) * 0.73);
  width: var(--rec-d);
  height: var(--rec-d);
  transform: rotate(var(--tilt)) scaleY(var(--depth));
}
.record__disc { position: absolute; inset: 0; width: 100%; max-width: none; height: 100%; }

/* 0-0.5 s the form fades out. 0.15-1.05 s the record rises 48px into place and fades in while
   Mochi moves down onto it, both on the same easing so his feet meet the surface as both stop.
   At 1.05 s the record starts to turn (easing up to speed over 0.8 s, then one turn every 10 s)
   as Mochi starts walking. */
.entry__form { transition: opacity 0.5s ease, visibility 0s linear 0.5s; }
.entry .clip--mochi { transition: transform 0.9s cubic-bezier(0.3, 0, 0.2, 1) 0.15s; }
.entry.is-sending .clip--mochi { transform: translateY(var(--drop, 0px)); }
/* On the crimson record his crimson linework needs an edge: a fine blue outline, the colour of
   the screen, so it can't be seen anywhere but over the record. It is in the video and the still
   (tools/mochi_alpha_fix.py). The approved drop-shadows stay on the video too: on iPhones they
   keep it on the drawing path that shows him walking (without them he vanished there). The
   file's transparent pixels are empty, so this path no longer shows a box. */
.entry.is-sending .clip--mochi video { filter: drop-shadow(0 0 0.5px #5FA8C2) drop-shadow(0 0 0.5px #5FA8C2) drop-shadow(0 0 0.5px #5FA8C2); }
/* The still (the video's first frame) covers the video until app.js has seen the walk drawn
   (.is-live); if the video never plays, he stays as the still. */
.entry .clip--mochi .mochi-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  pointer-events: none;
}
.entry .clip--mochi.is-live .mochi-still { visibility: hidden; }
.entry.is-sending .record-stage {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.6s ease 0.15s, transform 0.9s cubic-bezier(0.3, 0, 0.2, 1) 0.15s;
}
.entry.is-walking .record__disc {
  animation: record-spin-up 0.8s cubic-bezier(0.333, 0, 0.667, 0.333) both, record-spin 10s linear 0.8s infinite;
}
/* The spin-up is a smooth ease-in that ends at exactly the steady speed (14.4 deg over 0.8 s). */
@keyframes record-spin-up { from { transform: rotate(0deg); } to { transform: rotate(-14.4deg); } }
@keyframes record-spin { from { transform: rotate(-14.4deg); } to { transform: rotate(-374.4deg); } }
