/* =============================================================================
   Celebrate - page components
   Loaded alongside app.css on every page except the editor.
   ========================================================================== */

/* =========================================================================
   Hero (spec 3/67)
   ====================================================================== */
.hero {
  position: relative;
  padding: clamp(36px, 5vw, 64px) 0 clamp(56px, 8vw, 104px);
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 78% 22%, var(--blush) 0%, transparent 58%),
    radial-gradient(90% 80% at 12% 90%, color-mix(in srgb, var(--gold) 14%, transparent) 0%, transparent 62%),
    linear-gradient(170deg, var(--cream) 0%, var(--cream-deep) 55%, var(--paper) 100%);
}

/* Soft botanical wash in the corners: two blurred leaf shapes, drawn rather
   than photographed, so the far edges of the hero have depth at no cost. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  width: clamp(200px, 26vw, 400px);
  aspect-ratio: 1;
  background:
    radial-gradient(closest-side, color-mix(in srgb, var(--sage) 34%, transparent), transparent 70%);
  filter: blur(14px);
  opacity: .5;
  pointer-events: none;
}
.hero::before { top: -8%; left: -7%; }
.hero::after { bottom: -14%; right: -5%; opacity: .32; }

.hero__grid {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(36px, 5vw, 60px);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 1000px) {
  .hero__grid { grid-template-columns: 1fr .95fr; }
}

/* Eyebrow with the hairline rule the design runs beside it. */
.hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.hero__eyebrow::after {
  content: "";
  height: 1px;
  width: clamp(28px, 5vw, 64px);
  background: color-mix(in srgb, var(--gold-deep) 45%, transparent);
}

/* Smaller than the generic d1: the headline shares its row with the card
   stage, and "Beautiful invitations." has to hold one line to read as the
   two-line statement the design is built around. */
.hero__title {
  margin-bottom: 20px;
  letter-spacing: -.02em;
  line-height: 1.02;
  font-size: clamp(2.35rem, 4.4vw, 3.6rem);
}
.hero__lede { max-width: 46ch; margin-bottom: 26px; }
/* One word picked out in the subheading, the way the design does it. */
.hero__lede i { font-style: normal; color: var(--gold-deep); }

/* The small line under the buttons, with its heart. */
.hero__note {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.hero__note svg { color: var(--rose); flex: none; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.hero__note { margin-top: 24px; }

/* Three reassurances under the buttons, each with its own small mark. */
.hero__points {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px clamp(16px, 2.4vw, 30px);
  margin-top: 26px;
}
/* The label wraps within its own item rather than pushing the third point on
   to a second row, which is how the three stay on one line. */
.hero__point {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  max-width: 11em;
  font-size: .72rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.hero__point svg {
  width: 30px;
  height: 30px;
  flex: none;
  padding: 7px;
  border-radius: 9px;
  background: var(--white);
  color: var(--evergreen);
  box-shadow: var(--shadow-xs);
}
.hero__point + .hero__point { border-left: 1px solid var(--line); padding-left: clamp(16px, 2.4vw, 30px); }
@media (max-width: 540px) {
  .hero__point + .hero__point { border-left: 0; padding-left: 0; }
}

/* --------------------------------------------------------- the card stage */
.hero__stage {
  position: relative;
  width: 100%;
  max-width: 700px;
  margin-inline: auto;
}

/* The hero photograph: an empty cream pedestal among white roses, eucalyptus
   and a gold ribbon, with the cards standing on it.
 *
 * The pedestal is deliberately bare. The cards are the real invitation
 * designs, rendered live above this, so they follow the catalogue and cannot
 * be baked into a picture.
 *
 * It hangs off the stage rather than off the section, because the section is
 * as wide as the window while the stage tracks the content column. Pinned to
 * the section, the pedestal drifted hundreds of pixels away from the cards on
 * a wide monitor; pinned to the stage, it stays under them at every width.
 * The generous negative insets let it bleed past the cards, and the section's
 * own `overflow: hidden` trims it at the edges of the band. */
.hero__stage::before {
  content: "";
  position: absolute;
  z-index: -1;

  /* Placed by arithmetic rather than by eye, because the cards have to look
     like they are standing on the pedestal and "nearly" reads as floating.
     In the photograph the pedestal's centre is at 0.72 of the image width and
     its top surface at 0.60 of the height. The box below is 200% of the stage
     wide and the image is locked to that width, so the pedestal centre lands
     at (0.5 - 0.72 x 2) = -0.94 of a stage-width from the stage's left edge -
     which is the stage's own centre, under the fan. `top` then drops the
     image until that surface meets the base of the cards. `cover` cannot be
     used here: it rescales with the box's aspect ratio, so the pedestal
     wandered off the cards at other window sizes. */
  top: 3.5%;
  right: -10.7%;
  bottom: -40%;
  left: -89.3%;
  background-image: url("/assets/img/hero-stage.webp");
  background-repeat: no-repeat;
  background-size: 100% auto;
  background-position: left top;
  pointer-events: none;

  /* Feathered on all four sides so the photograph dissolves into the cream
     instead of ending on a visible rectangle. Two fades intersected: one
     across, one down. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 20%, #000 82%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 22%, #000 86%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, transparent 0, #000 20%, #000 82%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 22%, #000 86%, transparent 100%);
  mask-composite: intersect;
}

/* Stacked layout. The same arithmetic, re-run: the fan is square here rather
   than slightly landscape, so the drop that puts the pedestal under the cards
   is a different fraction of the stage. */
@media (max-width: 999px) {
  .hero__stage::before {
    top: 4%;
    right: .9%;
    bottom: -42%;
    left: -100.9%;
    background-image: url("/assets/img/hero-stage-sm.webp");
  }
}

/* Fanned invitation cards. Asymmetric, with a gentle parallax drift. */
.fan {
  position: relative;
  aspect-ratio: 1 / .92;
  width: 100%;
}

/* The plinth the cards stand on: a warm ellipse of light plus its shadow. */
.fan::before {
  content: "";
  position: absolute;
  left: 50%; bottom: 4%;
  translate: -50% 0;
  width: 76%;
  height: 16%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(92, 68, 40, .28), transparent 72%);
  filter: blur(10px);
}

.fan__card {
  position: absolute;
  width: 46%;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 30px 60px -26px rgba(74, 52, 30, .5), 0 2px 0 rgba(255, 255, 255, .7) inset;
  background: var(--white);
  transition: transform .9s var(--ease-out), box-shadow .5s var(--ease);
  will-change: transform;
}
/* Spread wide enough that each card reads as its own design rather than a
   sliver behind the one in front: the fan is the product demo. */
.fan__card:nth-child(1) { left: -4%;  top: 20%; rotate: -12deg; z-index: 1; width: 38%; }
.fan__card:nth-child(2) { left: 22%;  top: 2%;  rotate: -2deg;  z-index: 4; width: 44%; }
.fan__card:nth-child(3) { right: 12%; top: 15%; rotate: 8deg;   z-index: 3; width: 38%; }
.fan__card:nth-child(4) { right: -6%; top: 30%; rotate: 16deg;  z-index: 2; width: 33%; }
.fan__card:hover { box-shadow: 0 40px 76px -26px rgba(74, 52, 30, .58); z-index: 6; }

/* ------------------------------------------------------ live RSVP widget */
/* The product's actual promise, shown rather than described. Numbers are
   illustrative and marked as such for assistive technology. */
.rsvp-peek {
  position: absolute;
  right: -4%;
  bottom: -4%;
  width: min(258px, 58%);
  padding: 16px 18px;
  border-radius: 18px;
  background: color-mix(in srgb, var(--white) 92%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid color-mix(in srgb, var(--white) 70%, var(--line));
  box-shadow: 0 24px 50px -22px rgba(74, 52, 30, .42);
  z-index: 7;
}
.rsvp-peek__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.rsvp-peek__title { font-size: .84rem; font-weight: 600; }
.rsvp-peek__live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: .64rem;
  font-weight: 650;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ok);
}
.rsvp-peek__live::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ok);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }

.rsvp-peek__body { display: flex; align-items: center; gap: 16px; }

/* Donut drawn with a conic gradient: no chart library, no canvas. */
.rsvp-peek__dial {
  position: relative;
  width: 74px; height: 74px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(
    var(--ok) 0 var(--yes),
    var(--warn) var(--yes) var(--maybe),
    var(--line) var(--maybe) 100%);
}
.rsvp-peek__dial::after {
  content: "";
  position: absolute;
  inset: 11px;
  border-radius: 50%;
  background: var(--white);
}
.rsvp-peek__count {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  z-index: 1;
  line-height: 1.1;
}
.rsvp-peek__count b { font-size: 1.22rem; font-weight: 650; }
.rsvp-peek__count span { font-size: .54rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

.rsvp-peek__key { display: grid; gap: 7px; font-size: .76rem; }
.rsvp-peek__row { display: flex; align-items: center; gap: 8px; }
.rsvp-peek__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.rsvp-peek__row b { font-weight: 600; }
.rsvp-peek__row span { color: var(--muted); }

.rsvp-peek__link {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  font-size: .7rem;
  font-weight: 650;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--evergreen);
  text-decoration: none;
}
.rsvp-peek__link:hover { gap: 10px; }

/* The aside the design sets at the top right of the stage, beside its heart. */
.hero__script {
  position: absolute;
  top: -2%;
  right: 0;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: .7rem;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-align: right;
  color: var(--muted);
  z-index: 6;
  pointer-events: none;
}
.hero__script svg { color: var(--rose); flex: none; order: 2; }

@media (max-width: 1000px) {
  .hero__script { display: none; }
}
@media (max-width: 640px) {
  .hero__stage { max-width: 440px; }
  .fan { aspect-ratio: 1 / 1; }
  .fan__card:nth-child(4) { display: none; }
  .rsvp-peek { right: 50%; translate: 50% 0; bottom: -4%; width: min(260px, 88%); }
}

/* =========================================================================
   Sections
   ====================================================================== */
.section { padding: clamp(52px, 7vw, 92px) 0; }
.section--tight { padding: clamp(36px, 5vw, 60px) 0; }
.section--paper { background: var(--paper-2); }
.section--ink { background: var(--ink); color: var(--paper); }
.section--ink .muted, .section--ink .lede { color: color-mix(in srgb, var(--paper) 72%, transparent); }
.section--ink .eyebrow { color: var(--gold); }

.section__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: clamp(26px, 3.6vw, 44px);
}
.section__head p { max-width: 56ch; margin: 10px 0 0; }
.section__head--center { flex-direction: column; align-items: center; text-align: center; }
.section__head--center p { margin-inline: auto; }

/* A kicker set on the title's own baseline rather than stacked above it, so
   the heading reads as one line: "Popular invitations  DESIGNS PEOPLE LOVE". */
.section__title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 16px; }
.section__kicker {
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* The quiet aside the design puts at the far right of a section heading. */
.section__aside {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.section__aside svg { color: var(--rose); flex: none; }
@media (max-width: 860px) { .section__aside { display: none; } }

/* =========================================================================
   Template grid (spec 5)
   ====================================================================== */
.tpl-grid {
  display: grid;
  gap: clamp(16px, 2.4vw, 28px);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) { .tpl-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .tpl-grid { grid-template-columns: repeat(4, 1fr); } }
.tpl-grid--wide { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .tpl-grid--wide { grid-template-columns: repeat(3, 1fr); } }

.tpl {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
}
/* A tight 5px corner, not the 18px the rest of the furniture uses. A printed
   invitation has a nearly square corner, and a heavy radius on the frame reads
   as the card itself being rounded. */
.tpl__media {
  position: relative;
  border-radius: 5px;
  overflow: hidden;
  background: var(--paper-2);
  box-shadow: var(--shadow-sm);
  transition: transform .45s var(--ease-out), box-shadow .45s var(--ease);
}
.tpl:hover .tpl__media,
.tpl:focus-visible .tpl__media {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
}
.tpl__overlay {
  position: absolute;
  inset: auto 0 0;
  padding: 44px 14px 14px;
  background: linear-gradient(to top, rgba(20, 18, 16, .62), transparent);
  opacity: 0;
  transition: opacity .35s var(--ease);
  display: flex;
  justify-content: center;
}
.tpl:hover .tpl__overlay, .tpl:focus-within .tpl__overlay { opacity: 1; }
.tpl__cta {
  background: var(--white);
  color: var(--ink);
  border-radius: var(--r-pill);
  padding: 9px 18px;
  font-size: .82rem;
  font-weight: 600;
}
.tpl__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 2px 0;
}
.tpl__title { font-size: .94rem; font-weight: 550; }
.tpl__tier { font-size: .76rem; color: var(--muted); }
.tpl__flags {
  position: absolute;
  top: 10px; left: 10px;
  display: flex;
  gap: 6px;
  z-index: 2;
}

.fav {
  position: absolute;
  top: 10px; right: 10px;
  z-index: 3;
  width: 34px; height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 0;
  background: color-mix(in srgb, var(--white) 84%, transparent);
  backdrop-filter: blur(6px);
  cursor: pointer;
  color: var(--ink-soft);
  transition: transform .2s var(--ease-out), color .2s var(--ease), background-color .2s;
}
.fav:hover { transform: scale(1.08); background: var(--white); }
.fav svg { width: 17px; height: 17px; }
.fav[aria-pressed="true"] { color: var(--rose); }
.fav[aria-pressed="true"] svg { fill: currentColor; }

/* =========================================================================
   Occasion tiles
   ====================================================================== */
/* A single row of pills that wraps, rather than a rigid grid: the number of
   occasions is an administrator's decision, so the layout cannot assume one. */
.occasions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.occasion {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 20px 11px 12px;
  border-radius: var(--r-pill);
  background: var(--white);
  border: 1px solid var(--line-soft);
  text-decoration: none;
  font-size: .9rem;
  font-weight: 500;
  white-space: nowrap;
  transition: transform .25s var(--ease-out), border-color .25s var(--ease),
              box-shadow .25s, background-color .25s var(--ease);
}
.occasion:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--sw, var(--gold)) 45%, transparent);
  box-shadow: var(--shadow-sm);
}

/* The mark sits in a tinted disc keyed to the occasion's own colour. */
.occasion__icon {
  display: grid;
  place-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  flex: none;
  background: color-mix(in srgb, var(--sw, var(--gold)) 16%, var(--white));
  color: color-mix(in srgb, var(--sw, var(--gold)) 78%, var(--ink));
}
.occasion__icon svg { width: 17px; height: 17px; }

.occasion__swatch {
  width: 26px; height: 26px;
  border-radius: 8px;
  flex: none;
  background: var(--sw, var(--gold));
  opacity: .9;
}

/* =========================================================================
   Steps / features
   ====================================================================== */
.steps {
  display: grid;
  gap: clamp(20px, 3vw, 34px);
  grid-template-columns: 1fr;
  counter-reset: step;
}
@media (min-width: 760px) { .steps { grid-template-columns: repeat(4, 1fr); } }
.step { position: relative; padding-top: 26px; }
.step::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  position: absolute;
  top: 0; left: 0;
  font-family: var(--font-display);
  font-size: .96rem;
  color: var(--gold-deep);
  letter-spacing: .06em;
}
.step h3 { font-size: 1.06rem; margin-bottom: 7px; font-weight: 550; }
.step p { font-size: .92rem; color: var(--ink-soft); }

/* ---- The three-step version used on the homepage, with the numeral set in
   a disc beside the text and a connector drawn between the cards. -------- */
.steps--major {
  gap: clamp(18px, 2.4vw, 28px);
  counter-reset: bigstep;
}
@media (min-width: 860px) { .steps--major { grid-template-columns: repeat(3, 1fr); } }

.step--major {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 24px 22px;
  border-radius: var(--r-lg);
  background: var(--white);
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-xs);
}
.step--major::before { content: none; }
.step--major .step__n {
  counter-increment: bigstep;
  display: grid;
  place-content: center;
  width: 44px; height: 44px;
  flex: none;
  border-radius: 50%;
  background: var(--evergreen-tint);
  color: var(--evergreen);
  font-family: var(--font-display);
  font-size: 1.12rem;
}
.step--major .step__n::after { content: counter(bigstep, decimal-leading-zero); }
.step--major h3 { margin-bottom: 6px; }

/* Connector arrows between steps, hidden when the cards stack. */
.steps--major .step--major { position: relative; }
@media (min-width: 860px) {
  .steps--major .step--major:not(:last-child)::after {
    content: "";
    position: absolute;
    right: calc(-1 * clamp(18px, 2.4vw, 28px) / 2 - 5px);
    top: 50%;
    width: 10px; height: 10px;
    translate: 0 -50%;
    rotate: 45deg;
    border-top: 1.5px solid var(--faint);
    border-right: 1.5px solid var(--faint);
  }
}

/* =========================================================================
   Horizontal carousel for template rows
   ====================================================================== */
.rail { position: relative; }

.rail__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(190px, 1fr);
  gap: clamp(12px, 1.6vw, 20px);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* Room for the cards' lift on hover, and for the focus ring. */
  padding: 6px 2px 14px;
  margin-inline: -2px;
}
.rail__track::-webkit-scrollbar { display: none; }
.rail__track > * { scroll-snap-align: start; }

@media (min-width: 700px)  { .rail__track { grid-auto-columns: minmax(210px, 1fr); } }
@media (min-width: 1100px) { .rail__track { grid-auto-columns: minmax(0, 1fr); } }

/* On wide screens the row shows six and scrolls only if there are more. */
@media (min-width: 1100px) {
  .rail__track { grid-auto-columns: calc((100% - 5 * clamp(12px, 1.6vw, 20px)) / 6); }
}

.rail__nav {
  position: absolute;
  top: 38%;
  z-index: 3;
  display: grid;
  place-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: opacity .2s var(--ease), background-color .2s, transform .2s var(--ease-out);
}
.rail__nav:hover { background: var(--paper); transform: translateY(-1px); }
.rail__nav--prev { left: clamp(-20px, -1.4vw, -8px); }
.rail__nav--next { right: clamp(-20px, -1.4vw, -8px); }
.rail__nav[disabled] { opacity: 0; pointer-events: none; }

@media (max-width: 760px) { .rail__nav { display: none; } }

/* ---- Showcase row --------------------------------------------------------
   Each design is shown whole. The row used to crop to a 3:2 band, which fit
   more cards across but sliced the top and bottom off designs that are
   portrait - taking the headline the card is named after with them. Nothing
   here declares an aspect ratio: the renderer puts the design's own ratio on
   the canvas, so the frame follows the artwork instead of dictating to it,
   and a landscape design added later would need no change. */
.rail--wide .rail__track { grid-auto-columns: minmax(220px, 1fr); }
@media (min-width: 1100px) {
  .rail--wide .rail__track {
    grid-auto-columns: calc((100% - 5 * clamp(12px, 1.6vw, 20px)) / 6);
  }
}

.rail--wide .tpl__media > a { display: block; }
.rail--wide .tpl__meta {
  justify-content: center;
  padding-top: 11px;
}
.rail--wide .tpl__tier { display: none; }
.rail--wide .tpl__title { font-size: .9rem; font-weight: 500; }

.features {
  display: grid;
  gap: clamp(16px, 2.4vw, 26px);
  grid-template-columns: 1fr;
}
@media (min-width: 680px) { .features { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .features { grid-template-columns: repeat(3, 1fr); } }

.feature {
  padding: clamp(22px, 3vw, 30px);
  border-radius: var(--r-lg);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.feature__icon {
  width: 42px; height: 42px;
  border-radius: 13px;
  display: grid;
  place-items: center;
  background: var(--paper-2);
  color: var(--gold-deep);
  margin-bottom: 15px;
}
.feature__icon svg { width: 21px; height: 21px; }
.feature h3 { font-size: 1.02rem; margin-bottom: 7px; font-weight: 550; }
.feature p { font-size: .91rem; color: var(--ink-soft); margin: 0; }

/* =========================================================================
   Testimonials
   ====================================================================== */
.quotes {
  display: grid;
  gap: clamp(16px, 2.4vw, 26px);
  grid-template-columns: 1fr;
}
@media (min-width: 760px) { .quotes { grid-template-columns: repeat(3, 1fr); } }
.quote {
  padding: clamp(22px, 3vw, 30px);
  border-radius: var(--r-lg);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.quote blockquote {
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-size: 1.1rem;
  line-height: 1.45;
}
.quote figcaption { font-size: .84rem; color: var(--muted); }
.quote__stars { color: var(--gold); letter-spacing: .12em; margin-bottom: 13px; font-size: .82rem; }

/* =========================================================================
   Pricing (spec 37)
   ====================================================================== */
.plans {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 860px) { .plans { grid-template-columns: repeat(3, 1fr); } }

.plan {
  position: relative;
  padding: clamp(24px, 3.4vw, 34px);
  border-radius: var(--r-lg);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.plan--featured {
  border-color: var(--ink);
  box-shadow: var(--shadow);
}
.plan__flag {
  position: absolute;
  top: -12px; left: 50%;
  translate: -50% 0;
  padding: 5px 15px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--white);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 600;
}
.plan__name { font-size: 1.1rem; font-weight: 600; margin-bottom: 4px; }
.plan__price {
  display: flex;
  align-items: baseline;
  gap: 5px;
  margin: 16px 0 6px;
}
.plan__amount { font-family: var(--font-display); font-size: 3rem; line-height: 1; }
.plan__period { color: var(--muted); font-size: .9rem; }
.plan__sub { font-size: .86rem; color: var(--muted); min-height: 1.4em; }
.plan__list { margin: 22px 0; }
.plan__list li {
  display: flex;
  gap: 10px;
  padding: 6px 0;
  font-size: .9rem;
  color: var(--ink-soft);
}
.plan__list svg { width: 17px; height: 17px; flex: none; margin-top: 3px; color: var(--sage); }

.billing-toggle {
  display: inline-flex;
  padding: 4px;
  border-radius: var(--r-pill);
  background: var(--paper-2);
  margin-bottom: 34px;
}
.billing-toggle button {
  border: 0;
  background: transparent;
  padding: 9px 20px;
  border-radius: var(--r-pill);
  font-size: .88rem;
  font-weight: 550;
  cursor: pointer;
  color: var(--muted);
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.billing-toggle button[aria-pressed="true"] {
  background: var(--white);
  color: var(--ink);
  box-shadow: var(--shadow-xs);
}

/* =========================================================================
   FAQ
   ====================================================================== */
.faq { max-width: 760px; margin-inline: auto; }
.faq details {
  border-bottom: 1px solid var(--line-soft);
  padding: 4px 0;
}
.faq summary {
  padding: 18px 40px 18px 0;
  cursor: pointer;
  font-weight: 550;
  font-size: 1rem;
  list-style: none;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: 6px; top: 50%;
  width: 11px; height: 11px;
  border-right: 1.6px solid var(--muted);
  border-bottom: 1.6px solid var(--muted);
  translate: 0 -60%;
  rotate: 45deg;
  transition: rotate .25s var(--ease);
}
.faq details[open] summary::after { rotate: -135deg; translate: 0 -30%; }
.faq details p { padding: 0 20px 20px 0; color: var(--ink-soft); font-size: .94rem; }

/* =========================================================================
   Marketplace filters (spec 5)
   ====================================================================== */
.filters {
  position: sticky;
  top: var(--nav-h);
  z-index: 40;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-soft);
  padding: 14px 0;
  margin-bottom: 32px;
}
.filters__row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.filters__search { position: relative; flex: 1 1 260px; min-width: 200px; }
.filters__search svg {
  position: absolute;
  left: 14px; top: 50%;
  translate: 0 -50%;
  width: 17px; height: 17px;
  color: var(--faint);
  pointer-events: none;
}
.filters__search .input { padding-left: 42px; border-radius: var(--r-pill); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 15px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--white);
  font-size: .85rem;
  color: var(--ink-soft);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .18s var(--ease), background-color .18s var(--ease), color .18s;
}
.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip[aria-pressed="true"], .chip.is-on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--white);
}
.chip__swatch { width: 13px; height: 13px; border-radius: 50%; border: 1px solid rgba(0,0,0,.12); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chips--scroll {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-behavior: smooth;
  padding-bottom: 2px;
  -webkit-overflow-scrolling: touch;
}
.chips--scroll::-webkit-scrollbar { display: none; }

/* ---- A chip row that scrolls ---------------------------------------------
   Hiding the scrollbar left the last chip sliced flat against the edge, which
   reads as a broken layout rather than "there is more this way". The row now
   fades out where it continues and carries arrows on pointer devices. */
.chip-bar { position: relative; }

.chip-bar .chips--scroll {
  /* Fades are applied per side, and only when that side has more to show. */
  --fade-start: transparent 0, #000 0;
  --fade-end: #000 calc(100% - 0px), transparent 100%;
  -webkit-mask-image: linear-gradient(to right, var(--fade-start)), linear-gradient(to right, var(--fade-end));
  mask-image: linear-gradient(to right, var(--fade-start)), linear-gradient(to right, var(--fade-end));
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  transition: -webkit-mask-image .2s var(--ease), mask-image .2s var(--ease);
}
.chip-bar[data-more-start="true"] .chips--scroll { --fade-start: transparent 0, #000 44px; }
.chip-bar[data-more-end="true"]   .chips--scroll { --fade-end: #000 calc(100% - 44px), transparent 100%; }

.chip-bar__nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  z-index: 3;
  display: grid;
  place-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: opacity .2s var(--ease), background-color .2s var(--ease);
}
.chip-bar__nav:hover { background: var(--paper); }
.chip-bar__nav--prev { left: -6px; }
.chip-bar__nav--next { right: -6px; }
.chip-bar__nav[disabled] { opacity: 0; pointer-events: none; }

/* Touch devices swipe; the arrows would only be in the way. */
@media (hover: none), (max-width: 700px) { .chip-bar__nav { display: none; } }

.filter-drawer { display: none; }
.filter-drawer[data-open="true"] { display: block; }
.filter-drawer__grid {
  display: grid;
  gap: 18px 24px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  padding: 18px 0 4px;
}
.filter-drawer h4 {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
  font-weight: 600;
}

/* =========================================================================
   Template detail (spec 6)
   ====================================================================== */
.tpl-detail {
  display: grid;
  gap: clamp(28px, 5vw, 60px);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) { .tpl-detail { grid-template-columns: 1.05fr .95fr; } }

.preview-tabs { display: flex; gap: 6px; margin-bottom: 18px; }
.preview-stage {
  display: grid;
  place-items: center;
  padding: clamp(18px, 3vw, 38px);
  border-radius: var(--r-lg);
  background: var(--paper-2);
  min-height: 300px;
}
.preview-stage--desktop { background: var(--ink); }
.device-desktop {
  width: 100%;
  max-width: 620px;
  border-radius: 12px 12px 0 0;
  background: #2a2724;
  padding: 26px 12px 12px;
  position: relative;
}
.device-desktop::before {
  content: "";
  position: absolute;
  top: 9px; left: 14px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #56514b;
  box-shadow: 14px 0 0 #56514b, 28px 0 0 #56514b;
}
.device-desktop__screen {
  background: var(--paper);
  border-radius: 4px;
  padding: 22px;
  display: grid;
  place-items: center;
}
.device-phone {
  width: 260px;
  border-radius: 34px;
  background: #2a2724;
  padding: 11px;
  box-shadow: var(--shadow-lg);
}
.device-phone__screen {
  background: var(--paper);
  border-radius: 25px;
  overflow: hidden;
  padding: 14px;
}

/* =========================================================================
   Dashboard (spec 25/35)
   ====================================================================== */
.dash {
  display: grid;
  gap: 0;
  grid-template-columns: 1fr;
  min-height: calc(100vh - var(--nav-h));
}
@media (min-width: 1000px) { .dash { grid-template-columns: 250px 1fr; } }

.dash__side {
  padding: 28px var(--gutter);
  border-right: 1px solid var(--line-soft);
  background: var(--paper);
}
@media (max-width: 999px) {
  .dash__side {
    border-right: 0;
    border-bottom: 1px solid var(--line-soft);
    padding-bottom: 12px;
  }
  .dash__nav { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
  .dash__nav::-webkit-scrollbar { display: none; }
  .dash__side h3 { display: none; }
}
.dash__main { padding: clamp(24px, 3.4vw, 40px) var(--gutter) 80px; min-width: 0; }

.dash__nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 13px;
  border-radius: var(--r-sm);
  font-size: .91rem;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .16s var(--ease), color .16s;
}
.dash__nav a:hover { background: var(--paper-2); color: var(--ink); }
.dash__nav a[aria-current="page"] { background: var(--ink); color: var(--white); font-weight: 500; }
.dash__nav a svg { width: 17px; height: 17px; flex: none; }
.dash__side h3 {
  font-size: .72rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 22px 0 8px 13px;
  font-weight: 600;
}
.dash__side h3:first-child { margin-top: 0; }

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 28px;
}
.page-head h1 { margin-bottom: 5px; }

.stat-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, 1fr);
  margin-bottom: 26px;
}
@media (min-width: 720px) { .stat-grid { grid-template-columns: repeat(5, 1fr); } }
.stat {
  padding: 17px 19px;
  border-radius: var(--r);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.stat__value { font-family: var(--font-display); font-size: 1.85rem; line-height: 1; }
.stat__label { font-size: .76rem; color: var(--muted); margin-top: 6px; letter-spacing: .04em; }
.stat--accent { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.stat--accent .stat__label { color: color-mix(in srgb, var(--paper) 66%, transparent); }

.progress {
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--paper-3);
  overflow: hidden;
  display: flex;
}
.progress span { display: block; height: 100%; transition: width .6s var(--ease-out); }
.progress .is-going { background: var(--ok); }
.progress .is-maybe { background: var(--warn); }
.progress .is-no { background: color-mix(in srgb, var(--danger) 55%, var(--paper-3)); }

.event-card {
  display: grid;
  gap: 18px;
  grid-template-columns: 96px 1fr;
  align-items: center;
  padding: 16px;
  border-radius: var(--r);
  background: var(--white);
  border: 1px solid var(--line-soft);
  text-decoration: none;
  color: inherit;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), transform .2s var(--ease-out);
}
.event-card:hover { border-color: var(--line); box-shadow: var(--shadow-sm); transform: translateY(-2px); }
.event-card__thumb { border-radius: var(--r-xs); overflow: hidden; background: var(--paper-2); }
.event-card h3 { font-size: 1.02rem; margin-bottom: 3px; font-weight: 550; }

/* --------------------------------------------------------------- tables */
.table-wrap {
  overflow-x: auto;
  border-radius: var(--r);
  border: 1px solid var(--line-soft);
  background: var(--white);
  -webkit-overflow-scrolling: touch;
}
.table { min-width: 720px; font-size: .9rem; }
.table th {
  text-align: left;
  padding: 12px 16px;
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
  background: var(--paper);
  position: sticky;
  top: 0;
}
.table td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--paper); }
.table__name { font-weight: 550; }
.table__sub { font-size: .8rem; color: var(--muted); }

.bulk-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 16px;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--white);
  font-size: .88rem;
  margin-bottom: 14px;
}
.bulk-bar .btn { --btn-bg: rgba(255,255,255,.14); --btn-fg: #fff; }
.bulk-bar .btn:hover { --btn-bg: rgba(255,255,255,.24); }

.empty {
  text-align: center;
  padding: clamp(40px, 7vw, 72px) 24px;
  border-radius: var(--r-lg);
  border: 1px dashed var(--line);
  background: var(--white);
}
.empty__icon {
  width: 54px; height: 54px;
  margin: 0 auto 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--paper-2);
  color: var(--gold-deep);
}
.empty h3 { font-size: 1.14rem; margin-bottom: 7px; }
.empty p { color: var(--muted); max-width: 44ch; margin-inline: auto; margin-bottom: 20px; }

/* --------------------------------------------------------------- tabs */
.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line-soft);
  margin-bottom: 26px;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  padding: 11px 15px;
  font-size: .9rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.tabs a:hover { color: var(--ink); }
.tabs a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink); font-weight: 550; }

/* =========================================================================
   Public event page (spec 26/62)
   ====================================================================== */
.invite-page {
  min-height: 100vh;
  background: var(--ev-bg, var(--paper));
  color: var(--ev-ink, var(--ink));
}
.invite-hero {
  padding: clamp(26px, 5vw, 60px) var(--gutter) clamp(30px, 5vw, 56px);
  display: grid;
  place-items: center;
}
.invite-hero__card { width: min(520px, 100%); }

.invite-body {
  max-width: 660px;
  margin-inline: auto;
  padding: 0 var(--gutter) 90px;
}

.ev-section { padding: clamp(26px, 4vw, 44px) 0; border-top: 1px solid var(--line-soft); }
.ev-section:first-child { border-top: 0; }
.ev-section h2 {
  font-size: .76rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 18px;
  font-weight: 600;
}

.detail-list { display: grid; gap: 2px; }
.detail-list > div {
  display: grid;
  grid-template-columns: 116px 1fr;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: .95rem;
}
.detail-list > div:last-child { border-bottom: 0; }
.detail-list dt { color: var(--muted); font-size: .82rem; letter-spacing: .02em; }
.detail-list dd { margin: 0; }
@media (max-width: 520px) {
  .detail-list > div { grid-template-columns: 1fr; gap: 2px; }
}

.rsvp-choices {
  display: grid;
  gap: 10px;
  grid-template-columns: 1fr;
  margin-bottom: 22px;
}
@media (min-width: 520px) { .rsvp-choices { grid-template-columns: repeat(3, 1fr); } }

.rsvp-choice {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 18px 14px;
  border-radius: var(--r);
  border: 1.5px solid var(--line);
  background: var(--white);
  cursor: pointer;
  font-weight: 550;
  font-size: .95rem;
  text-align: center;
  transition: border-color .2s var(--ease), background-color .2s var(--ease), transform .2s var(--ease-out);
}
.rsvp-choice:hover { transform: translateY(-2px); border-color: var(--ink); }
.rsvp-choice input { position: absolute; opacity: 0; pointer-events: none; }
.rsvp-choice:has(input:checked) {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--white);
}
.rsvp-choice:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 3px; }

.gallery {
  display: grid;
  gap: 8px;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 620px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
.gallery figure {
  margin: 0;
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--r-xs);
  overflow: hidden;
  background: var(--paper-2);
}
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease-out); }
.gallery figure:hover img { transform: scale(1.04); }
.gallery__actions {
  position: absolute;
  inset: auto 0 0;
  padding: 26px 8px 8px;
  background: linear-gradient(to top, rgba(0,0,0,.55), transparent);
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  opacity: 0;
  transition: opacity .25s var(--ease);
}
.gallery figure:hover .gallery__actions { opacity: 1; }

.signup-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line-soft);
}
.signup-item:last-child { border-bottom: 0; }
.signup-item__names { font-size: .84rem; color: var(--muted); }

.registry-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 15px 18px;
  border-radius: var(--r);
  background: var(--white);
  border: 1px solid var(--line-soft);
  text-decoration: none;
  margin-bottom: 9px;
  transition: border-color .2s var(--ease), transform .2s var(--ease-out);
}
.registry-link:hover { border-color: var(--ink); transform: translateY(-2px); }

/* Share panel (spec 21) */
.share-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) { .share-grid { grid-template-columns: repeat(4, 1fr); } }
.share-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px;
  border-radius: var(--r);
  background: var(--white);
  border: 1px solid var(--line-soft);
  font-size: .82rem;
  text-decoration: none;
  color: var(--ink-soft);
  cursor: pointer;
  transition: transform .2s var(--ease-out), border-color .2s var(--ease);
}
.share-btn:hover { transform: translateY(-3px); border-color: var(--ink); color: var(--ink); }
.share-btn svg { width: 22px; height: 22px; }

.copy-row {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 7px 7px 7px 16px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--white);
}
.copy-row input {
  flex: 1;
  border: 0;
  background: transparent;
  font-size: .88rem;
  color: var(--ink-soft);
  min-width: 0;
  padding: 6px 0;
}
.copy-row input:focus { outline: none; }

.qr-box {
  display: inline-block;
  padding: 14px;
  border-radius: var(--r);
  background: var(--white);
  border: 1px solid var(--line-soft);
}
.qr-box svg, .qr-box img { width: 168px; height: 168px; }

/* =========================================================================
   Auth pages
   ====================================================================== */
.auth {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 940px) { .auth { grid-template-columns: 1fr 1fr; } }
.auth__form {
  display: grid;
  place-items: center;
  padding: clamp(32px, 6vw, 72px) var(--gutter);
}
.auth__inner { width: min(410px, 100%); }
.auth__aside {
  display: none;
  position: relative;
  background: var(--ink);
  color: var(--paper);
  padding: 60px 48px;
  overflow: hidden;
  place-items: center;
}
@media (min-width: 940px) { .auth__aside { display: grid; } }
.auth__aside::before {
  content: "";
  position: absolute;
  inset: -30% -20% auto;
  aspect-ratio: 1;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--gold) 28%, transparent), transparent 70%);
}
.auth__quote { position: relative; max-width: 420px; }

.strength { display: flex; gap: 4px; margin-top: 8px; }
.strength span {
  height: 3px;
  flex: 1;
  border-radius: 2px;
  background: var(--line);
  transition: background-color .3s var(--ease);
}
.strength[data-score="1"] span:nth-child(-n+1) { background: var(--danger); }
.strength[data-score="2"] span:nth-child(-n+2) { background: var(--warn); }
.strength[data-score="3"] span:nth-child(-n+3) { background: var(--gold); }
.strength[data-score="4"] span { background: var(--ok); }

/* =========================================================================
   Admin
   ====================================================================== */
.admin-metrics {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, 1fr);
  margin-bottom: 30px;
}
@media (min-width: 760px) { .admin-metrics { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1200px) { .admin-metrics { grid-template-columns: repeat(6, 1fr); } }

.spark {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 42px;
  margin-top: 12px;
}
.spark i {
  flex: 1;
  background: color-mix(in srgb, var(--gold) 55%, var(--paper-3));
  border-radius: 2px 2px 0 0;
  min-height: 2px;
}

/* =========================================================================
   Modal
   ====================================================================== */
dialog.modal {
  border: 0;
  padding: 0;
  border-radius: var(--r-lg);
  width: min(560px, calc(100vw - 32px));
  background: var(--white);
  box-shadow: var(--shadow-lg);
  color: inherit;
}
dialog.modal::backdrop { background: rgba(24, 21, 18, .44); backdrop-filter: blur(3px); }
dialog.modal[open] { animation: modal-in .24s var(--ease-out); }
@keyframes modal-in {
  from { opacity: 0; transform: translateY(12px) scale(.98); }
  to { opacity: 1; transform: none; }
}
.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 24px;
  border-bottom: 1px solid var(--line-soft);
}
.modal__body { padding: 24px; max-height: min(66vh, 620px); overflow-y: auto; }
.modal__foot {
  padding: 16px 24px;
  border-top: 1px solid var(--line-soft);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  background: var(--paper);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* =========================================================================
   Print (invitation and guest list)
   ====================================================================== */
@media print {
  .site-head, .site-foot, .btn, .filters, .dash__side, .flash-stack { display: none !important; }
  body { background: #fff; }
  .card, .table-wrap { border: 1px solid #ddd; box-shadow: none; }
  a[href]::after { content: ""; }
}
