/* ==========================================================================
   Akshay & Nishika — five cards, full screen, turned by hand.

   The turn itself is StPageFlip (vendor/), which folds and bends the sheet
   rather than pivoting it like a rigid board. What lives here is the room
   around it: the out-of-focus backdrop, the paper, and the controls.
   ========================================================================== */

:root {
  --void:   #0B0E0A;
  --stock:  #F7F2E4;

  --gold:     #C08A2E;
  --gold-lit: #D9A441;

  /* how long the flip takes; kept in step with flippingTime in script.js */
  --flip-ms: 900ms;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--void);
  overscroll-behavior: none;
}

body {
  color: var(--stock);
  font-family: "Marcellus", "Iowan Old Style", Palatino, Georgia, serif;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* --------------------------------------------------------------------------
   The backdrop

   A 9:16 card cannot fill a 16:9 screen without cutting the artwork, so the
   leftover space takes the same image thrown far out of focus. The screen is
   full, and nothing is cropped.
   -------------------------------------------------------------------------- */

.veil {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--void);
}

.veil-layer {
  position: absolute;
  inset: -14%;
  background-position: center;
  background-size: cover;
  filter: blur(72px) saturate(1.45) brightness(.6);
  transform: scale(1.08);
  opacity: 0;
  transition: opacity 900ms ease;
  will-change: opacity;
}

.veil-layer.on { opacity: 1; }

.veil-scrim {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(74% 58% at 50% 44%, transparent 0%, rgba(7, 9, 6, .62) 100%);
}

/* --------------------------------------------------------------------------
   The stage

   #flip is StPageFlip's parent, so it gets the whole viewport. In portrait
   mode the library fits the page inside that box on its own, keeping the
   941 x 1672 proportion: full height on a desktop, full width on a phone.
   -------------------------------------------------------------------------- */

.stage {
  position: fixed;
  inset: 0;
  z-index: 1;
}

/* StPageFlip copies its `minWidth` setting onto this element as a CSS
   min-width. That setting exists only to hold the library in single-card
   (portrait) mode — see script.js — so the width it writes has to be
   overruled, or the card is laid out against a 9000px box and lands off
   screen. */
#flip {
  width: 100%;
  height: 100%;
  min-width: 0 !important;
  min-height: 0 !important;
}

.source { display: none; }

/* a card. StPageFlip sizes these itself, so set no width or height here */
.page {
  overflow: hidden;
  background: var(--stock);
  box-shadow: 0 10px 34px rgba(0, 0, 0, .42), 0 40px 90px rgba(0, 0, 0, .34);
}

.page img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}

/* The face that comes up as a sheet folds over — tagged in script.js. These
   cards are printed on one side, so the artwork is dropped there and the
   page's own cream stock shows through as a blank back. */
.page.reverse img { display: none; }

/* paper grain, over the print and over the blank back alike */
.page::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: .05;
  mix-blend-mode: multiply;
}

/* --------------------------------------------------------------------------
   The sound switch

   Deliberately not part of the bar below, and deliberately does not fade:
   turning music off is the one thing somebody may need to do in a hurry.
   -------------------------------------------------------------------------- */

.sound {
  position: fixed;
  z-index: 3;
  top: calc(16px + env(safe-area-inset-top, 0px));
  right: 16px;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--stock) 24%, transparent);
  border-radius: 50%;
  background: rgba(8, 10, 6, .46);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  color: color-mix(in oklab, var(--stock) 78%, transparent);
  cursor: pointer;
  transition: color 220ms ease, border-color 220ms ease, background-color 220ms ease;
}

.sound[hidden] { display: none; }

/* both icons stack in the one cell; only one is ever shown */
.sound svg {
  grid-area: 1 / 1;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sound .sound-on  { display: none; }
.sound .sound-off { display: block; }
.sound[aria-pressed="true"] .sound-on  { display: block; }
.sound[aria-pressed="true"] .sound-off { display: none; }

.sound[aria-pressed="true"] {
  color: var(--gold-lit);
  border-color: color-mix(in oklab, var(--gold-lit) 56%, transparent);
}

.sound:hover {
  color: var(--gold-lit);
  border-color: color-mix(in oklab, var(--gold-lit) 72%, transparent);
}

.sound:focus-visible { outline: 1px solid var(--gold-lit); outline-offset: 3px; }

/* --------------------------------------------------------------------------
   Controls, floating over the card and stepping aside when unused
   -------------------------------------------------------------------------- */

.hud {
  position: fixed;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 18px 20px calc(18px + env(safe-area-inset-bottom, 0px));
  /* the cards run bright right to their bottom edge, so the label needs a
     ground under it rather than a shadow alone */
  background: linear-gradient(to top, rgba(5, 7, 4, .84) 0%, rgba(5, 7, 4, .54) 54%, transparent 100%);
  transition: background 520ms ease;
}

/* The controls step aside when unused, but the way on stays — dimmed, and
   still clickable. On a full screen with nothing else on it, that is the one
   thing somebody has to be able to find. */
.hud.idle {
  background: linear-gradient(to top, rgba(5, 7, 4, .5) 0%, transparent 100%);
}

.hud.idle .directions,
.hud.idle .meter,
.hud.idle #prev { opacity: 0; pointer-events: none; }
.hud.idle #next { opacity: .72; }
.hud.idle #next:disabled { opacity: .16; }

.controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 4vw, 28px);
}

/* --------------------------------------------------------------------------
   Getting there

   Four of the five cards name a venue. This carries that address out to a
   map; the invitation itself names none, so on that card it is not there at
   all rather than sitting dead.
   -------------------------------------------------------------------------- */

.directions {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 17px 9px 14px;
  border: 1px solid color-mix(in oklab, var(--gold-lit) 48%, transparent);
  border-radius: 999px;
  background: rgba(8, 10, 6, .5);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  color: color-mix(in oklab, var(--stock) 92%, transparent);
  font-size: 11px;
  letter-spacing: .2em;
  text-indent: .2em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 520ms ease, color 220ms ease,
              border-color 220ms ease, background-color 220ms ease;
}

/* beats the display above, so the invitation loses the row entirely */
.directions[hidden] { display: none; }

.directions svg {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: var(--gold-lit);
  stroke-width: 1.45;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.directions:hover {
  color: var(--stock);
  border-color: color-mix(in oklab, var(--gold-lit) 80%, transparent);
  background: color-mix(in oklab, var(--gold) 20%, rgba(8, 10, 6, .5));
}

.directions:focus-visible { outline: 1px solid var(--gold-lit); outline-offset: 3px; }

/* a disc under each one, because the cards are bright enough at the bottom
   edge that a bare stroke disappears into the artwork */
.nav {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 1px solid color-mix(in oklab, var(--stock) 24%, transparent);
  border-radius: 50%;
  background: rgba(8, 10, 6, .46);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  color: color-mix(in oklab, var(--stock) 80%, transparent);
  cursor: pointer;
  transition: opacity 520ms ease, color 220ms ease,
              border-color 220ms ease, background-color 220ms ease;
}

.nav svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Next is the way through the invitation, so it carries the weight: wider,
   ringed in the gold the cards are engraved in, and it stays put. Back is
   the quieter of the two — it is only ever a correction. */
#next {
  width: 50px;
  height: 50px;
  border-color: color-mix(in oklab, var(--gold-lit) 64%, transparent);
  background: color-mix(in oklab, var(--gold) 22%, rgba(8, 10, 6, .52));
  color: var(--gold-lit);
  box-shadow: 0 2px 16px rgba(0, 0, 0, .5), 0 0 0 0 rgba(217, 164, 65, .42);
}

#next svg { width: 21px; height: 21px; stroke-width: 1.65; }

.nav:hover {
  color: var(--gold-lit);
  border-color: color-mix(in oklab, var(--gold-lit) 72%, transparent);
}

#next:hover { background: color-mix(in oklab, var(--gold) 36%, rgba(8, 10, 6, .52)); }

.nav:focus-visible { outline: 1px solid var(--gold-lit); outline-offset: 3px; }

/* until the first card is turned, a slow breath off the ring — enough to
   catch the eye on a screen with no other furniture on it */
#next.nudge { animation: breathe 2600ms ease-in-out infinite; }

@keyframes breathe {
  0%, 100% { box-shadow: 0 2px 16px rgba(0, 0, 0, .5), 0 0 0 0 rgba(217, 164, 65, .42); }
  62%      { box-shadow: 0 2px 16px rgba(0, 0, 0, .5), 0 0 0 12px rgba(217, 164, 65, 0); }
}

.nav:disabled {
  opacity: .16;
  cursor: default;
  color: color-mix(in oklab, var(--stock) 60%, transparent);
  /* no frosted disc where there is no button to press */
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* spent, at the last card — the gold comes off so it reads as done */
#next:disabled {
  color: color-mix(in oklab, var(--stock) 60%, transparent);
  border-color: color-mix(in oklab, var(--stock) 24%, transparent);
  background: rgba(8, 10, 6, .46);
  box-shadow: none;
  animation: none;
}

.meter {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  min-width: 150px;
  transition: opacity 520ms ease;
}

.caption {
  margin: 0;
  font-size: 12px;
  letter-spacing: .34em;
  text-indent: .34em;
  text-transform: uppercase;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .7);
  color: color-mix(in oklab, var(--stock) 88%, transparent);
  transition: opacity 240ms ease;
}

.caption.swap { opacity: 0; }

.register {
  display: flex;
  align-items: flex-end;
  gap: 9px;
  height: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tick {
  width: 1px;
  height: 7px;
  background: color-mix(in oklab, var(--stock) 34%, transparent);
  transition: height 380ms ease, background-color 380ms ease;
}

.tick.on {
  height: 14px;
  background: var(--gold-lit);
}

.hint {
  position: fixed;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  margin: 0;
  text-align: center;
  font-size: 10px;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  text-shadow: 0 1px 10px rgba(0, 0, 0, .8);
  color: color-mix(in oklab, var(--stock) 42%, transparent);
  pointer-events: none;
  transition: opacity 800ms ease;
}

.hint.gone { opacity: 0; }

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .veil-layer { transition-duration: 1ms; }
  #next.nudge { animation: none; }
}
