/* ==========================================================================
   Birthday Treasure Hunt: invitation styles
   Zero+ brand palette: deep purple ground, cream bands, orange accent.
   ========================================================================== */

:root {
  /* Palette sampled from the Zero+ brand board: the orange (#f28020), the
     magenta panel (#880064, deepened here so body text clears AA on it) and
     the purples the artwork is printed on. */
  --plum:        #1e0630;   /* the page itself */
  --plum-lift:   #2b0a42;   /* cards and raised surfaces */
  --magenta:     #880064;   /* the board's magenta, the mark on light */
  --paper:       #f7eff7;   /* body text */
  --paper-dim:   #c3aacd;   /* secondary text */
  --orange:      #f28020;   /* the one accent */
  --orange-soft: #f89b4d;   /* large figures and links */
  --on-orange:   #2b0742;   /* text sitting on an orange fill */
  --ok:          #5fd39b;
  --bad:         #ff9184;
  --ok-rgb:      95 211 155;
  --bad-rgb:     255 145 132;

  /* Channel values, so every translucent layer is mixed from the palette
     above rather than from a hard-coded colour that drifts out of step. */
  --plum-rgb:    30 6 48;
  --paper-rgb:   247 239 247;
  --orange-rgb:  242 128 32;
  --magenta-rgb: 136 0 100;

  /* Hairlines are orange, echoing the outline drawings on the brand board. */
  --line:        rgb(var(--orange-rgb) / 0.30);

  /* Two tokens the light sections re-point at themselves: the fill behind a
     form field, and the colour of small accent marks. Buttons are not among
     them, so the call to action stays orange the whole way down the page. */
  --field:       var(--plum);
  --mark:        var(--orange);
  --mark-rgb:    var(--orange-rgb);

  /* Headings use the body face at a heavier weight rather than a separate
     display face. Point --display at another family to change that back. */
  --body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --display: var(--body);

  --wrap:   68rem;
  --gutter: 1.25rem;
  --radius: 14px;

  /* Tells the browser to draw radios, spinners and scrollbars dark, so
     an unchecked radio is not a white blob that reads as "selected". */
  color-scheme: dark;
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--plum);
  color: var(--paper);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.65;
  overflow-x: hidden;
}

img, svg { max-width: 100%; }

a { color: var(--mark); }

/* Two soft washes of brand colour behind everything, so the deep purple
   has some depth without any pattern drawn over it. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse 70% 55% at 16% 6%,  rgb(var(--orange-rgb) / 0.10), transparent 72%),
    radial-gradient(ellipse 65% 50% at 88% 74%, rgb(var(--magenta-rgb) / 0.22), transparent 72%);
}

main, .topbar, .footer { position: relative; z-index: 1; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Narrow sections keep a readable line length, but line up on the left with
   the full-width sections above rather than sitting centred in the page. */
.wrap.narrow { max-width: var(--wrap); }
.wrap.narrow > * { max-width: 42rem; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: 0.75rem 1rem;
  background: var(--orange);
  color: var(--plum);
  font-weight: 600;
  z-index: 50;
}
.skip-link:focus { left: 0; }

/* ---------------------------------------------------------------- topbar */

.topbar {
  position: sticky;
  /* Clears the notch on an iPhone, since the page opts into the full screen. */
  top: env(safe-area-inset-top, 0px);
  z-index: 20;
  backdrop-filter: blur(10px);
  background: rgb(var(--plum-rgb) / 0.82);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 3.75rem;
}

.mark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: 0.01em;
  overflow: hidden;
}
.mark span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mark svg { width: 1.35rem; height: 1.35rem; flex: none; color: var(--mark); }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.75rem 1.35rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--orange);
  color: var(--on-orange);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.btn:hover { background: var(--orange-soft); }
.btn:active { transform: translateY(1px); }

.btn-ghost {
  background: transparent;
  color: var(--paper);
  border-color: rgb(var(--paper-rgb) / 0.28);
}
.btn-ghost:hover { background: rgb(var(--paper-rgb) / 0.08); border-color: var(--mark); }

.btn-sm  { padding: 0.45rem 0.95rem; font-size: 0.875rem; }
.btn-lg  { padding: 0.9rem 1.75rem; font-size: 1.0625rem; }
.btn-block { width: 100%; margin-top: 0.5rem; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--mark);
  outline-offset: 3px;
  border-radius: 6px;
}

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

.hero {
  position: relative;
  padding: clamp(3rem, 9vw, 6rem) 0 clamp(2.5rem, 6vw, 4rem);
}

.eyebrow {
  margin: 0 0 1rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--mark);
}

.hero h1 { margin: 0; display: grid; gap: 0.15em; }

.hero-name {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(2.5rem, 11vw, 5.5rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: var(--paper);
}

.hero-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.35rem, 5vw, 2.35rem);
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--paper);
}

.lede {
  max-width: 34ch;
  margin: 1.5rem 0 0;
  font-size: clamp(1.05rem, 2.6vw, 1.3rem);
  color: var(--paper-dim);
}

.facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 2rem 0 0;
  padding: 0;
  list-style: none;
}
.facts li {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.55rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(var(--paper-rgb) / 0.04);
  font-size: 0.9375rem;
  font-weight: 500;
}
.facts svg { width: 1.05rem; height: 1.05rem; flex: none; color: var(--mark); }

.aside {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin: 1.25rem 0 0;
  color: var(--paper-dim);
  font-size: 0.9375rem;
}
.aside svg { width: 1.1rem; height: 1.1rem; flex: none; margin-top: 0.25rem; color: var(--mark); }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.25rem;
}

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

/* The photograph runs the full width with the headline standing on it, and
   the rest of the hero sits below on the purple. The scrim is weighted to
   the bottom, so the words get a dark ground to sit on while the sunrise
   and the spire above them stay untouched. */

.hero.has-photo { padding-top: 0; }

.hero > .wrap { position: relative; z-index: 2; }

.hero-photo {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(19rem, 58vh, 34rem);
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
  overflow: hidden;
}

.hero-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Holds the spire and the sunrise, cropping the empty road away first. */
  object-position: center 46%;
}

.hero-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgb(var(--plum-rgb) / 0.32) 0%,
    rgb(var(--plum-rgb) / 0)    26%,
    rgb(var(--plum-rgb) / 0.55) 58%,
    rgb(var(--plum-rgb) / 0.9)  84%,
    var(--plum)                 100%
  );
}

.hero-headline {
  position: relative;
  z-index: 2;
  padding-bottom: clamp(1.25rem, 3.5vw, 2.25rem);
}

/* A little lift for the few places the photograph runs pale behind a letter. */
.hero-headline .hero-name,
.hero-headline .hero-title {
  text-shadow: 0 1px 14px rgb(var(--plum-rgb) / 0.55);
}

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

.countdown {
  margin-top: 2.75rem;
  padding: 1.25rem 1.25rem 1.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgb(var(--paper-rgb) / 0.06), rgb(var(--paper-rgb) / 0.02));
  max-width: 34rem;
}

.countdown-label {
  margin: 0 0 0.85rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper-dim);
}

.countdown-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
  text-align: center;
}
.countdown-grid strong {
  display: block;
  font-family: var(--display);
  font-size: clamp(1.5rem, 6vw, 2.25rem);
  font-weight: 700;
  line-height: 1.1;
  color: var(--orange-soft);
  font-variant-numeric: tabular-nums;
}
.countdown-grid span {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-dim);
}

/* ------------------------------------------------------------------ bands */

.band { padding: clamp(2.75rem, 7vw, 4.5rem) 0; }

/* The alternating sections are light. Rather than restyling every component
   inside them, the section re-points the tokens its children already read:
   surfaces go pale, text goes dark, and small accent marks switch from the
   orange to the brand magenta, which carries far better on a cream ground.
   Buttons keep their own orange, so the call to action never changes. */
.band-alt {
  --plum:        #faf6f2;   /* the band */
  --plum-lift:   #ffffff;   /* cards standing on it */
  --field:       #ffffff;   /* form fields */
  --paper:       #2b0742;   /* text */
  --paper-dim:   #6b5875;   /* secondary text */
  --plum-rgb:    250 246 242;
  --paper-rgb:   43 7 66;
  --mark:        var(--magenta);
  --mark-rgb:    var(--magenta-rgb);
  --line:        rgb(var(--paper-rgb) / 0.14);

  /* Darkened so status messages still clear AA against the pale ground. */
  --ok:          #1b7a4b;
  --bad:         #b3261e;
  --ok-rgb:      27 122 75;
  --bad-rgb:     179 38 30;

  /* Native controls must be drawn light in here too, or an unchecked radio
     renders as a dark filled circle and reads as already selected. */
  color-scheme: light;

  background: var(--plum);
  color: var(--paper);
  border-block: 1px solid rgb(var(--paper-rgb) / 0.08);
}

/* An orange fill on a pale ground is only 2.5:1 against it, so the button
   needs its own edge for its shape to read. */
.band-alt .btn { border-color: rgb(var(--paper-rgb) / 0.22); }
.band-alt .btn-ghost { border-color: rgb(var(--paper-rgb) / 0.28); }


.section-title {
  margin: 0 0 1.75rem;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.6rem, 4.5vw, 2.25rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.muted { color: var(--paper-dim); }
.center { text-align: center; }

/* ------------------------------------------------------------------ steps */

.steps {
  display: grid;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.steps li {
  position: relative;
  padding: 1.5rem 1.4rem 1.4rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgb(var(--paper-rgb) / 0.03);
}
.step-num {
  font-family: var(--display);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--mark);
}
.steps h3 { margin: 0.35rem 0 0.5rem; font-size: 1.25rem; font-family: var(--display); }
.steps p  { margin: 0; color: var(--paper-dim); }

/* ------------------------------------------------------------------ cards */

.cards { display: grid; gap: 1rem; }

.card {
  padding: 1.35rem 1.35rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--plum-lift);
}
.card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 10px;
  background: rgb(var(--mark-rgb) / 0.14);
  color: var(--mark);
}
.card-icon svg { width: 1.3rem; height: 1.3rem; }
.card h3 { margin: 0.85rem 0 0.4rem; font-size: 1.0625rem; }
.card p  { margin: 0; color: var(--paper-dim); font-size: 0.9375rem; }

/* ------------------------------------------------------- where it starts */

.big-note {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 1.25rem;
  border: 1px dashed rgb(var(--mark-rgb) / 0.4);
  border-radius: var(--radius);
  background: rgb(var(--mark-rgb) / 0.06);
  font-size: 1.0625rem;
}
.big-note svg { width: 1.35rem; height: 1.35rem; flex: none; margin-top: 0.2rem; color: var(--mark); }

.share { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.5rem; }

/* ------------------------------------------------------------------- form */

.rsvp-form { margin-top: 1.75rem; display: grid; gap: 1.15rem; }

.field { display: grid; gap: 0.4rem; margin: 0; padding: 0; border: 0; }

.field > label,
.field > legend {
  padding: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.req { color: var(--mark); }
.hint-inline { font-weight: 400; color: var(--paper-dim); }

.hint { margin: -0.5rem 0 0; font-size: 0.8125rem; color: var(--paper-dim); }

input[type="text"], input[type="email"], input[type="tel"],
input[type="number"], input[type="password"], textarea {
  width: 100%;
  padding: 0.8rem 0.95rem;
  border: 1px solid rgb(var(--paper-rgb) / 0.2);
  border-radius: 10px;
  background: var(--field);
  color: var(--paper);
  font: inherit;
}
input::placeholder, textarea::placeholder { color: rgb(var(--paper-rgb) / 0.6); }
input:focus, textarea:focus { border-color: var(--mark); }
textarea { resize: vertical; min-height: 5.5rem; }

.row { display: grid; gap: 1.15rem; }

.choices { display: grid; gap: 0.6rem; margin-top: 0.25rem; }

.choice {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.85rem 1rem;
  border: 1px solid rgb(var(--paper-rgb) / 0.2);
  border-radius: 10px;
  background: var(--field);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.choice:hover { border-color: rgb(var(--mark-rgb) / 0.6); }
.choice input {
  accent-color: var(--mark);
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  margin: 0;
}
.choice:has(input:checked) {
  border-color: var(--mark);
  background: rgb(var(--mark-rgb) / 0.1);
}

.error {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--bad);
  min-height: 0;
}
.error:empty { display: none; }

.form-status { margin: 0.25rem 0 0; font-size: 0.9375rem; text-align: center; }
.form-status:empty { display: none; }
.form-status.is-ok  { color: var(--ok); }
.form-status.is-bad { color: var(--bad); }

.flash {
  margin: 0 0 1rem;
  padding: 0.9rem 1.1rem;
  border-radius: 10px;
  border: 1px solid;
  font-size: 0.9375rem;
}
.flash-ok    { border-color: rgb(var(--ok-rgb) / 0.5); background: rgb(var(--ok-rgb) / 0.1); color: var(--ok); }
.flash-error { border-color: rgb(var(--bad-rgb) / 0.5); background: rgb(var(--bad-rgb) / 0.1); color: var(--bad); }

/* The honeypot: present for bots, gone for people and screen readers. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Sections only relevant to people who are coming. */
[data-if-attending][hidden] { display: none; }

/* The whole form, replaced by a thank-you once it is sent. */
.done {
  margin-top: 1.75rem;
  padding: 2rem 1.5rem;
  border: 1px solid rgb(var(--mark-rgb) / 0.45);
  border-radius: var(--radius);
  background: rgb(var(--mark-rgb) / 0.08);
  text-align: center;
}
.done h3 {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-size: 1.5rem;
}
.done p { margin: 0; color: var(--paper-dim); }

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

.footer {
  padding: 2rem 0 2.75rem;
  border-top: 1px solid var(--line);
  text-align: center;
  color: var(--paper-dim);
  font-size: 0.875rem;
}
.footer p { margin: 0; }

/* ----------------------------------------------------------- wider screens */

@media (min-width: 40rem) {
  .row   { grid-template-columns: 1fr 1fr; }
  .choices { grid-template-columns: 1fr 1fr; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 60rem) {
  .cards { grid-template-columns: repeat(3, 1fr); }
  .lede  { max-width: 46ch; font-size: 1.35rem; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* A guest printing the invitation should get something legible. */
@media print {
  .backdrop, .topbar, .hero-actions, .share, .rsvp-form, .countdown, .skip-link, .hero-photo { display: none !important; }
  body { background: #fff; color: #111; }
  .band-alt { background: #fff; }
  .hero-name, .hero-title { color: #111; text-shadow: none; }
  .muted, .card p, .steps p, .aside { color: #333; }
}
