/* The invitation's shared skeleton (source: invitated/_tools/core/; see invitated/CLAUDE.md).
   A site sets these before or after it, in its own style.css:
     --ink        dark colour of the menu's text and lines
     --bar-ink    dark colour of the bar's parts over a light screen (else --ink)
     --paper      light colour of the same on a dark page
     --loader-bg  the preloader's background (the gate's colour)
     --footer-bg, --footer-fg   the footer strip
     --font-ui    the bar's language code and menu, the footer's credit
   Screen heights (set by core.js): --hero-h, the window as the invitation opened in it (kept until
   the phone turns); --hero-grow, as far as an in-app browser has grown it since. */
:root {
  --pin-h: max(var(--hero-h, 100svh), var(--hero-grow, 0px));
  /* A screen that must cover the window whatever Safari's bars do: its largest, plus room for the
     see-through bottom bar (Safari shows what lies below the window through it). */
  --screen-full: calc(max(var(--hero-h, 100svh), var(--hero-grow, 0px), var(--lvh, 100lvh)) + 96px);
  --screen-w: 393px;
}
html { background: var(--top, var(--paper)); }
/* A desktop's margins take the colour of the screen in view (core.js keeps --side in step).
   A site's own css never gives body or html a background of its own. */
body { background: var(--side, var(--paper)); transition: background-color 0.5s ease; }
html.is-locked { overflow: hidden; }
.is-locked body { overflow: hidden; }

/* ---------- Preloader ---------- */
.loader {
  position: fixed;
  inset: 0 0 -40vh;
  padding-bottom: 40vh;
  z-index: 70;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 20px;
  background: var(--loader-bg, var(--bar-ink, var(--ink)));
  color: var(--loader-fg, var(--paper));
  transition: opacity 0.7s ease;
}
.loader__logo { width: 94.38px; height: 22px; opacity: 0.9; background: currentColor; -webkit-mask: url("../assets/icons/logo.svg") center / contain no-repeat; mask: url("../assets/icons/logo.svg") center / contain no-repeat; }
.loader__track { width: 132px; height: 1px; overflow: hidden; background: color-mix(in srgb, currentColor 18%, transparent); }
.loader__track i { display: block; width: calc(var(--load, 0) * 100%); height: 100%; background: currentColor; transition: width 0.4s cubic-bezier(0.22, 0.61, 0.36, 1); }
.loader.is-done { opacity: 0; pointer-events: none; }

/* ---------- Top bar ---------- */
.topbar {
  position: fixed;
  z-index: 30;
  top: 0;
  left: 50%;
  width: min(100%, var(--screen-w));
  translate: -50% 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  color: var(--paper);
  /* Solid: Safari 26 carries a fixed top bar's colour up into the strip behind the clock, and it
     takes only an opaque one. core.js sets --bar-tint from the screen under it. */
  background: var(--bar-tint, var(--ink));
  transition: translate 0.28s cubic-bezier(0.3, 0, 0.2, 1), background-color 0.35s ease, color 0.35s ease;
}
/* Once slid away the bar leaves the page (.is-gone): Safari 26 keeps a fixed bar's colour in its
   strip for as long as the bar is in the page, even slid away or invisible. */
.topbar.is-hidden { translate: -50% -100%; }
.topbar.is-gone { display: none; }
.topbar.is-dark { color: var(--bar-ink, var(--ink)); }
.is-locked .topbar { z-index: 60; } /* the gate carries the bar too */
@media (max-width: 600px) { .topbar { width: 100%; } }
.topbar__tools { display: flex; align-items: center; gap: 12px; }
.logo-svg { display: block; flex: none; width: 94.38px; height: 22px; }
.bar-icon { display: block; flex: none; }
.bar-icon--globe { width: 14.33px; height: 14.33px; margin: 0.83px; }
.bar-icon--chevron { width: 8px; height: 4.4px; margin: 4.8px 3px; }
.bar-icon--sound { width: 24px; height: 24px; }
.lang { position: relative; }
.lang__button { display: flex; align-items: center; gap: 4px; padding: 0; border: 0; background: none; color: inherit; font: 400 14px/18px var(--font-ui); letter-spacing: -0.01em; cursor: pointer; }
.lang .bar-icon--chevron { transition: rotate 0.25s ease; }
.lang.is-open .bar-icon--chevron { rotate: 180deg; }
.lang__menu {
  position: absolute;
  right: -6px;
  top: calc(100% + 12px);
  min-width: 140px;
  margin: 0;
  padding: 6px;
  list-style: none;
  border-radius: 10px;
  background: color-mix(in srgb, var(--paper) 92%, white);
  color: var(--ink);
  box-shadow: 0 0 0 0.6px color-mix(in srgb, var(--ink) 18%, transparent), 0 12px 28px color-mix(in srgb, var(--ink) 18%, transparent);
  animation: menu-in 0.25s cubic-bezier(0.22, 0.61, 0.36, 1);
}
@keyframes menu-in { from { opacity: 0; translate: 0 -6px; } }
.lang__menu button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: inherit;
  text-align: left;
  font: 400 16px/20px var(--font-ui);
  cursor: pointer;
  transition: background 0.2s ease;
}
.lang__menu button[aria-selected="true"] { background: color-mix(in srgb, var(--ink) 10%, transparent); }
@media (hover: hover) { .lang__menu button:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); } }
.sound { width: 24px; height: 24px; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; }
.sound.is-empty { opacity: 0.45; cursor: default; }
/* The wave runs through the ring while the music plays, and lies still and flat when it is off. */
.sound__wave { animation: wave-run 1.2s linear infinite paused; }
.sound[aria-pressed="true"] .sound__wave { animation-play-state: running; }
@keyframes wave-run { to { translate: -5px 0; } }
.sound__line { transform-box: view-box; transform-origin: 12px 12px; scale: 1 0.08; transition: scale 0.6s cubic-bezier(0.45, 0, 0.2, 1); }
.sound[aria-pressed="true"] .sound__line { scale: 1 1; }
@media (prefers-reduced-motion: reduce) { .sound__wave { animation: none; } }

/* ---------- Safari's bottom bar reads this strip (core.js: iPhone/iPad Safari only, the colour of the
   screen just above it). 16px: thinner, Safari doesn't take it. ---------- */
.safari-foot { position: fixed; left: 0; right: 0; bottom: 0; z-index: 35; height: 16px; pointer-events: none; }

/* ---------- Footer: the Invitated credit ---------- */
.footer {
  height: 62px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  background: var(--footer-bg, var(--ink));
  color: var(--footer-fg, var(--paper));
}
.credit { margin: 0; font: 400 16px/1 var(--font-ui); }
.credit a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.to-top { width: 32px; text-align: right; font: 400 22px/1 system-ui, sans-serif; color: inherit; text-decoration: none; }

/* ---------- The dress code's colours: plain swatches (fabric pictures only if a client asks) ---------- */
.swatch { display: block; flex: none; width: var(--swatch-size, 52px); height: var(--swatch-size, 52px); border-radius: 50%; background: var(--swatch); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 16%, transparent); }

/* ---------- Blocks that lift into place the first time they are scrolled to ---------- */
.is-animated .rise { opacity: 0; translate: 0 16px; }
.is-animated .rise.is-in {
  opacity: 1;
  translate: none;
  transition: opacity 0.7s ease var(--in, 0s), translate 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) var(--in, 0s);
}
@media (prefers-reduced-motion: reduce) { .is-animated .rise { opacity: 1; translate: none; } }

/* On a wide window the gate is the phone's screen too: in the page's column, not across the window
   (a cover picture across a monitor is a close-up of its middle). The sides take the page's colour. */
@media (min-width: 601px) {
  #gate { left: 50%; right: auto; width: var(--screen-w); translate: -50% 0; }
}
