/* ===========================================================================
   Thirty, Flirty & Thriving — Chiara Vedi's 30th
   ---------------------------------------------------------------------------
   Follows the invite artwork: a purple glitter ground with a cream arch panel
   outlined in pink, display type split across crimson / purple / teal, and the
   party's cast of objects (disco ball, cherries, butterflies, martini, lips)
   scattered round the arch.

   The whole theme is the custom properties below. Colours are chosen to match
   the artwork AND clear WCAG AA on the cream — the artwork's brightest teal and
   pink don't, so their darker cousins carry the text. See the Accessibility
   section of the README before re-pointing any of these.
   ======================================================================== */

:root {
  /* --- colour ----------------------------------------------------------- */
  --cream: #f7f0e2;
  --cream-soft: #fdf8ef;

  --glitter: #9d7fc7;
  --glitter-deep: #7f5fae;
  --glitter-light: #c3aede;

  --crimson: #c41a55; /* the guest of honour's name */
  --magenta: #d81b74; /* "thirty," */
  --purple: #6b2d9e; /* "flirty," */
  --purple-deep: #5b2a8a; /* the tagline */
  --pink: #d81b74; /* hearts, lips, star, swoosh */
  --pink-bright: #e8388a; /* the ampersand */
  --pink-soft: #f18cba;
  --pink-wash: #fbe7f1;
  --teal: #127d8a; /* "thriving" */
  --teal-ink: #0f6b76; /* small caps and focus rings */
  --lime: #6f8d17;

  --ink: #4a3550;
  --ink-soft: #6b5570;

  --silver: #b9b6c4;
  --silver-deep: #8d8a9c;

  /* --- type ------------------------------------------------------------- */
  /* Fraunces for the display: ball terminals and a slight wonk, so it reads as
     drawn rather than typeset. Yellowtail carries the hand-lettered words. */
  --font-display: 'Fraunces', Georgia, serif;
  --font-script: 'Yellowtail', 'Snell Roundhand', cursive;
  --font-body: 'Jost', 'Avenir Next', 'Segoe UI', system-ui, sans-serif;

  --step--1: clamp(0.78rem, 0.74rem + 0.2vw, 0.88rem);
  --step-0: clamp(1rem, 0.95rem + 0.25vw, 1.1rem);
  --step-1: clamp(1.15rem, 1.05rem + 0.5vw, 1.4rem);
  --step-2: clamp(1.45rem, 1.25rem + 1vw, 1.95rem);
  --step-3: clamp(1.9rem, 1.4rem + 2.4vw, 2.9rem);
  --step-4: clamp(2.6rem, 1.6rem + 5vw, 5.2rem);

  /* --- spacing & shape -------------------------------------------------- */
  --gap-xs: 0.4rem;
  --gap-s: 0.75rem;
  --gap-m: 1.25rem;
  --gap-l: 2.25rem;
  --radius: 18px;
  /* The arch: a tall elliptical top, squared off at the bottom. */
  --arch: 50% 50% 16px 16px / 32% 32% 16px 16px;
}

/* --------------------------------------------------------------- baseline */

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

/* The UA's `[hidden] { display: none }` loses on specificity to any class that
   sets display — `.form { display: flex }` in particular — so hiding the RSVP
   form after a submit silently did nothing. Make the attribute win everywhere. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  padding: clamp(0.5rem, 2.5vw, 2.5rem);
  min-height: 100vh;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  /* The invite's own glitter paper. A 520px tile from the source art, which
     repeats seamlessly, so one small file covers any viewport. */
  background-color: var(--glitter);
  background-image: url('../img/bg-glitter.webp');
  background-size: 310px 310px;
  background-repeat: repeat;
  -webkit-font-smoothing: antialiased;
}

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

.sheet {
  max-width: 44rem;
  margin: 0 auto;
}

/* ------------------------------------------------------------ the drawings */

/* Every decoration is a real image with its own shadow already baked in, so
   nothing here adds one. Width drives the size; height follows the art. */
.deco img {
  display: block;
  width: 100%;
  height: auto;
}

/* Deliberately no width here: each sparkle sets its own on .sp, and a rule at
   this specificity would override every one of them. */
.sparkles img {
  display: block;
  height: auto;
}

/* Small sparkles scattered inside the arch, as on the invite. Decorative
   only, so they sit behind the type and never intercept a click. */
.sparkles {
  position: absolute;
  inset: clamp(9px, 1.6vw, 16px);
  z-index: 1;
  pointer-events: none;
}

.sp {
  position: absolute;
  width: 2.6cqw;
  opacity: 0.85;
}

.sp--1 {
  top: 12%;
  left: 12%;
}
.sp--2 {
  width: 2cqw;
  top: 20%;
  right: 13%;
}
.sp--3 {
  width: 2.2cqw;
  top: 47%;
  left: 8%;
}
.sp--4 {
  top: 63%;
  right: 10%;
}
.sp--5 {
  width: 1.8cqw;
  bottom: 14%;
  left: 16%;
}

.ink--purple {
  color: var(--purple);
}

/* ------------------------------------------------------------------- hero */

.hero {
  position: relative;
  /* Same width as the panel below it. `container-type: inline-size` lets
     everything inside size itself in cqw — percentages of this element's own
     width — so the whole invite scales as one piece rather than the box
     stretching while the type stays put. */
  container-type: inline-size;
  margin: 0 auto;
  padding: 5cqw 7cqw 6cqw;
  text-align: center;
  background: var(--cream);
  border-radius: var(--arch);
  box-shadow: 0 24px 60px -32px #2c1440aa;
}

/* The thin pink outline that traces just inside the arch. */
.hero__frame {
  position: absolute;
  inset: clamp(9px, 1.6vw, 16px);
  border: 2px solid var(--pink-soft);
  border-radius: var(--arch);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 2;
}

/* --- the cast, placed round the arch --- */
.deco {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}

/* Each sits astride the arch edge — part on the cream, part on the glitter —
   which is what stops the panel reading as a plain rounded rectangle. */
.deco--disco {
  width: 29cqw;
  top: -7cqw;
  left: -7cqw;
}
.deco--star {
  width: 22cqw;
  top: -5cqw;
  right: -5.5cqw;
  transform: rotate(14deg);
}
.deco--cherries {
  width: 21cqw;
  top: 34%;
  left: -6cqw;
  transform: rotate(-12deg);
}
.deco--butterfly-a {
  width: 18cqw;
  top: 22%;
  right: -5cqw;
  transform: rotate(16deg);
}
.deco--butterfly-b {
  width: 23cqw;
  bottom: 18%;
  left: -6.5cqw;
  transform: rotate(-18deg);
}
.deco--martini {
  width: 19cqw;
  top: 48%;
  right: -5cqw;
  transform: rotate(10deg);
}
.deco--lips {
  width: 23cqw;
  bottom: 13%;
  right: -5.5cqw;
  transform: rotate(-14deg);
}

/* --- the type --- */

/* The kicker is set on a curve with SVG textPath, so it needs SVG's own text
   properties — `color` and `text-transform` do nothing to an SVG <text>. */
.welcome {
  display: block;
  width: 62cqw;
  margin: 0 auto;
  overflow: visible;
}

.welcome text {
  fill: var(--teal-ink);
  font-family: var(--font-body);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
}

.hero__heart {
  margin: -0.1rem 0 0;
}

.hero__heart img {
  width: 4.5cqw;
  height: auto;
  margin: 0 auto;
  display: block;
}

.tagline__star {
  width: 2.6cqw;
  height: auto;
}

/* The signature. The artwork letters these words in three different hands and
   lets them interlock; three tidy stacked lines would lose all its character.
   The script word is oversized and tilted so its ascenders cross the caps
   above, and the ampersand sits alongside rather than on its own line. */
.hero__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 15.5cqw, 8rem);
  font-weight: 900;
  font-variation-settings: 'SOFT' 40, 'WONK' 1;
  line-height: 0.92;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.hero__title .w {
  display: block;
}

.w--thirty {
  color: var(--magenta);
}

.w--flirty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.06em;
  margin-block: -0.12em -0.14em;
}

.w__script {
  font-family: var(--font-script);
  font-size: 1.35em;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  color: var(--purple);
  transform: rotate(-5deg);
  /* Yellowtail's descenders would otherwise be clipped by the line box. */
  padding-block: 0.1em;
}

.w__amp {
  font-size: 1.2em;
  line-height: 1;
  color: var(--pink-bright);
}

.w--thriving {
  color: var(--teal);
}

.tagline {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15em;
  margin: 3cqw 0 0;
  font-size: clamp(0.72rem, 2.5cqw, 1.15rem);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--purple-deep);
}

.tagline__pop {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  color: var(--magenta);
}

/* The brush swoosh, with the heart sitting on top of it. */
.swoosh {
  position: relative;
  width: 46cqw;
  margin: 4cqw auto 0;
  color: var(--pink);
}

.swoosh__heart {
  display: block;
  width: 4cqw;
  height: auto;
  margin: 0 auto -0.35rem;
  position: relative;
  z-index: 2;
}

.swoosh__stroke {
  display: block;
  width: 100%;
  height: auto;
}

.hero__name {
  margin: 0;
  font-family: var(--font-script);
  font-size: clamp(1.9rem, 9cqw, 4.6rem);
  line-height: 1.15;
  color: var(--crimson);
}

/* The hand-drawn underline beneath the name, from the invite. */
.hero__rule {
  display: block;
  width: 46cqw;
  height: auto;
  margin: 0.5cqw auto 2.5cqw;
}

.hero__occasion {
  margin: 0 0 5cqw;
  font-size: clamp(0.72rem, 2.4cqw, 1.1rem);
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--pink);
}

/* --------------------------------------------------------- the lower card */

.card-sheet {
  margin-top: clamp(1rem, 3vw, 2rem);
  padding: clamp(1.25rem, 4vw, 2.5rem) clamp(1.1rem, 4vw, 2.5rem) var(--gap-l);
  background: var(--cream-soft);
  border-radius: 22px;
  box-shadow: 0 24px 60px -34px #2c1440aa;
}

section {
  padding-block: var(--gap-l);
  border-top: 2px dashed var(--pink-soft);
}

.card-sheet > section:first-child {
  padding-top: var(--gap-s);
  border-top: 0;
}

.section__title {
  margin: 0 0 var(--gap-m);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 800;
  font-variation-settings: 'SOFT' 40, 'WONK' 1;
  text-align: center;
  color: var(--purple);
}

/* -------------------------------------------------------------- countdown */

.clock {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap-s);
  margin: 0;
  padding: 0;
  list-style: none;
}

.clock__unit {
  padding: var(--gap-s) var(--gap-xs);
  text-align: center;
  background: var(--pink-wash);
  border: 2px solid var(--pink-soft);
  border-radius: var(--radius);
}

.clock__unit b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 800;
  line-height: 1;
  color: var(--crimson);
  font-variant-numeric: tabular-nums;
}

.clock__unit span {
  font-size: var(--step--1);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.clock__message {
  margin: var(--gap-m) 0 0;
  text-align: center;
  font-family: var(--font-script);
  font-size: var(--step-2);
  color: var(--purple);
}

.clock__message:empty {
  display: none;
}

/* ---------------------------------------------------------------- details */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--gap-s);
  margin: 0;
}

.card {
  padding: var(--gap-m);
  background: var(--cream);
  border: 2px solid var(--purple);
  border-radius: var(--radius);
}

.card--wide {
  grid-column: 1 / -1;
}

.card dt {
  margin-bottom: var(--gap-xs);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--teal-ink);
}

.card dd {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  margin: 0;
}

.card dd strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--purple);
}

.card dd span {
  font-size: var(--step-0);
  color: var(--ink-soft);
}

/* --------------------------------------------------------------- calendar */

.calendar__lede,
.calendar__note {
  margin: 0 0 var(--gap-m);
  text-align: center;
  color: var(--ink-soft);
}

.calendar__note {
  margin: var(--gap-m) 0 0;
  font-size: var(--step--1);
}

.calendar__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-s);
  margin: 0;
}

/* ---------------------------------------------------------------- buttons */

.btn {
  display: inline-block;
  padding: 0.72em 1.7em;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 999px;
  border: 2px solid var(--crimson);
  cursor: pointer;
  transition:
    transform 0.15s ease,
    background-color 0.15s ease,
    color 0.15s ease;
}

.btn--primary {
  color: var(--cream-soft);
  background: var(--crimson);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--purple);
  border-color: var(--purple);
  transform: translateY(-2px);
}

.btn--ghost {
  color: var(--crimson);
  background: transparent;
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  color: var(--cream-soft);
  background: var(--crimson);
  transform: translateY(-2px);
}

.btn:disabled,
.btn.is-disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

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

/* ------------------------------------------------------------------- rsvp */

.rsvp__lede {
  margin: 0 0 var(--gap-m);
  text-align: center;
  color: var(--ink-soft);
}

.form {
  display: flex;
  flex-direction: column;
  gap: var(--gap-m);
  max-width: 26rem;
  margin: 0 auto;
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--gap-xs);
}

.field__label {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--purple);
}

.field__label em {
  font-style: normal;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: none;
  color: var(--ink-soft);
}

.field__input {
  padding: 0.75em 1em;
  font: inherit;
  color: var(--ink);
  background: var(--cream-soft);
  border: 2px solid var(--purple);
  border-radius: var(--radius);
}

.field__input--area {
  resize: vertical;
  min-height: 5.5rem;
  font-family: var(--font-body);
  line-height: 1.5;
}

.field__input:focus {
  border-color: var(--crimson);
}

.field__hint {
  font-size: var(--step--1);
  color: var(--ink-soft);
}

.choice {
  display: flex;
  flex-direction: column;
  gap: var(--gap-xs);
  margin: 0;
  padding: 0;
  border: 0;
}

.choice legend {
  margin-bottom: var(--gap-xs);
  padding: 0;
}

.choice__opt {
  display: flex;
  align-items: center;
  gap: var(--gap-s);
  padding: 0.7em 1em;
  background: var(--cream-soft);
  border: 2px solid var(--purple);
  border-radius: var(--radius);
  cursor: pointer;
}

.choice__opt:has(input:checked) {
  border-color: var(--crimson);
  background: var(--pink-wash);
}

.choice__opt input {
  accent-color: var(--crimson);
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
}

/* Hidden from people, visible to the bots we want to catch. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__status {
  margin: 0;
  min-height: 1.5em;
  font-size: var(--step--1);
  text-align: center;
}

.form__status--error {
  color: #b3164c;
  font-weight: 500;
}

.form__status--ok {
  color: var(--teal-ink);
  font-weight: 500;
}

.form__done {
  max-width: 26rem;
  margin: 0 auto;
  padding: var(--gap-m);
  text-align: center;
  background: var(--pink-wash);
  border: 2px solid var(--pink-soft);
  border-radius: var(--radius);
}

.form__done p {
  margin: 0 0 var(--gap-xs);
  color: var(--ink-soft);
}

.form__doneTitle {
  font-family: var(--font-script);
  font-size: var(--step-2);
  color: var(--crimson) !important;
}

/* ----------------------------------------------------------------- footer */

.foot__heart {
  width: 0.9rem;
  height: auto;
}

.foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-xs);
  padding-top: var(--gap-l);
  border-top: 2px dashed var(--pink-soft);
  font-size: var(--step--1);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--purple);
}

/* ------------------------------------------------------------------ admin */

.admin__title {
  margin: 0 0 var(--gap-l);
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 800;
  font-variation-settings: 'SOFT' 40, 'WONK' 1;
  text-align: center;
  color: var(--purple);
}

.sheet--admin {
  max-width: 52rem;
  padding: clamp(1.5rem, 4vw, 3rem);
  background: var(--cream-soft);
  border-radius: 22px;
  box-shadow: 0 24px 60px -34px #2c1440aa;
}

.gate,
.results {
  border-top: 0;
  padding-top: 0;
}

.tally {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap-s);
  margin: 0 0 var(--gap-m);
  padding: 0;
  list-style: none;
}

.tally__item {
  padding: var(--gap-s);
  text-align: center;
  background: var(--cream);
  border: 2px solid var(--purple);
  border-radius: var(--radius);
}

.tally__item b {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 800;
  line-height: 1;
  color: var(--purple);
}

.tally__item--yes {
  border-color: var(--teal);
}
.tally__item--yes b {
  color: var(--teal-ink);
}
.tally__item--no {
  border-color: var(--pink-soft);
}
.tally__item--no b {
  color: var(--crimson);
}

.tally__item span {
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.results__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-s);
  margin-bottom: var(--gap-s);
}

.table__scroll {
  overflow-x: auto;
}

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step-0);
}

.table th {
  padding: var(--gap-xs) var(--gap-s);
  text-align: left;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--purple);
  border-bottom: 2px solid var(--pink-soft);
  white-space: nowrap;
}

.table td {
  padding: var(--gap-xs) var(--gap-s);
  border-bottom: 1px solid #e7dcc9;
}

.table .is-yes {
  color: var(--teal-ink);
  font-weight: 600;
}
.table .is-no {
  color: var(--crimson);
}

/* Addresses stay on one line and the table scrolls instead — a mid-word break
   turns an email into something you can't read or copy at a glance. */
.table .is-email {
  color: var(--ink-soft);
  white-space: nowrap;
}

.table .is-note {
  min-width: 14rem;
  color: var(--ink);
}

.table__empty {
  text-align: center;
  color: var(--ink-soft);
  padding-block: var(--gap-m) !important;
}

/* ---------------------------------------------------------- small screens */

@media (max-width: 30rem) {
  .clock {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Keep the disco ball and the lips: the two that read at any size. */
  .deco--cherries,
  .deco--butterfly-a,
  .deco--butterfly-b,
  .deco--martini {
    display: none;
  }

  .tally {
    grid-template-columns: 1fr;
  }
}

/* One orchestrated page-load reveal rather than effects scattered about: the
   invite assembles itself once, top to bottom, and then sits still. */
@media (prefers-reduced-motion: no-preference) {
  .hero__inner > * {
    animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
  }

  .welcome,
  .hero__heart {
    animation-delay: 0.05s;
  }
  .hero__title {
    animation-delay: 0.13s;
  }
  .tagline {
    animation-delay: 0.3s;
  }
  .swoosh,
  .hero__name {
    animation-delay: 0.38s;
  }
  .hero__rule,
  .hero__occasion {
    animation-delay: 0.46s;
  }
  .hero__inner .btn {
    animation-delay: 0.54s;
  }

  .deco {
    animation: pop 0.8s 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2) backwards;
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

@keyframes pop {
  from {
    opacity: 0;
    scale: 0.7;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
