/* Kyren's 1st Birthday — shared styles for the invitation and the host dashboard */
:root{
  --paper:#F2EEE4;
  --card:#FDFBF5;
  --slate:#6E8AA6;
  --slate-ink:#42607E;
  --gold:#A98546;
  --gold-deep:#8C6C36;
  --sage:#8FA88D;
  --coral:#CC7059;
  --ink:#232E38;
  --muted:#717C86;
  --line:rgba(35,46,56,.13);
  --line-soft:rgba(35,46,56,.07);
  --shadow:0 1px 2px rgba(35,46,56,.04),0 12px 34px -12px rgba(35,46,56,.16);
  --r:16px;
  --tap:48px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur:.2s;
  /* None of the display faces above carry Chinese glyphs. Ending every family
     with the device's own CJK face keeps the Simplified Chinese wording in a
     face drawn for it, rather than whatever generic sans the browser would
     otherwise reach for. A line holding both scripts still takes each
     character from the first family that has it. */
  --cjk-sans:"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans SC",sans-serif;
  --cjk-serif:"Songti SC","Noto Serif SC",serif;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:"Barlow",system-ui,-apple-system,var(--cjk-sans);font-size:16px;line-height:1.5;
  -webkit-font-smoothing:antialiased;min-height:100vh;overflow-x:hidden;
}
/* paper grain + watercolour wash */
body::before{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='200' height='200' filter='url(%23n)' opacity='.22'/></svg>");
  mix-blend-mode:multiply}
body::after{content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(60% 40% at 8% 2%, rgba(143,168,141,.20), transparent 70%),
    radial-gradient(50% 36% at 96% 6%, rgba(110,138,166,.18), transparent 70%),
    radial-gradient(46% 34% at 98% 58%, rgba(204,112,89,.12), transparent 70%),
    radial-gradient(60% 40% at 0% 84%, rgba(169,133,70,.10), transparent 70%)}

.wrap{position:relative;z-index:2;max-width:600px;margin:0 auto;
  padding:24px 18px calc(48px + env(safe-area-inset-bottom))}
.wrap.wide{max-width:1060px}
.skip{position:absolute;left:-9999px}
.skip:focus{left:18px;top:12px;z-index:99;background:var(--card);padding:10px 14px;border-radius:8px;border:1px solid var(--line)}
:focus-visible{outline:2.5px solid var(--slate);outline-offset:3px;border-radius:6px}

/* ---------------- language switch ---------------- */
/* Above the invitation and aligned with it: the first thing a guest reading
   Chinese finds, and out of the way for everyone else. */
.langbar{position:relative;z-index:3;max-width:600px;margin:0 auto;
  padding:14px 18px 0;display:flex;justify-content:flex-end;gap:6px}
.langbar button{min-height:40px;padding:0 14px;border:1px solid var(--line);border-radius:999px;
  background:transparent;cursor:pointer;color:var(--muted);font:inherit;font-size:13px;font-weight:600;
  font-family:"Barlow Condensed",var(--cjk-sans);letter-spacing:.12em;text-transform:uppercase;
  transition:color var(--dur) var(--ease),background var(--dur) var(--ease),
             border-color var(--dur) var(--ease)}
.langbar button:hover{color:var(--ink)}
.langbar button[aria-pressed="true"]{background:var(--card);border-color:var(--slate);
  color:var(--slate-ink);box-shadow:var(--shadow);cursor:default}
/* The invitation begins right under the switch, so it needs less of its own. */
.langbar + .wrap{padding-top:10px}

/* Cormorant has no Chinese italic to lend, and a synthesised slant of a CJK
   face is a smear rather than an italic. */
html[lang^="zh"] .eyebrow{font-style:normal}

/* ---------------- invitation head ---------------- */
.invite{text-align:center;padding:6px 0 2px}
.eyebrow{font-family:"Cormorant Garamond",var(--cjk-serif);font-style:italic;font-weight:600;
  font-size:clamp(21px,5.6vw,28px);color:var(--gold);margin:0;letter-spacing:.01em}
h1.name{font-family:"Barlow Condensed",var(--cjk-sans);font-weight:600;text-transform:uppercase;
  color:var(--gold);font-size:clamp(46px,14vw,74px);line-height:.9;margin:.1em 0 0;letter-spacing:.005em}
h1.name .sub{display:block;font-weight:400;font-size:.55em;letter-spacing:.02em;margin-top:.12em}
.ribbon{display:inline-block;margin-top:16px;background:var(--gold);color:#FFFAF0;
  font-family:"Barlow Condensed",var(--cjk-sans);font-weight:600;letter-spacing:.16em;font-size:13px;
  text-transform:uppercase;padding:9px 30px;
  clip-path:polygon(0 0,100% 0,95% 50%,100% 100%,0 100%,5% 50%)}

.hero{display:grid;grid-template-columns:104px 1fr;gap:18px;align-items:center;
  margin:26px 0 24px;padding:18px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.hero svg{width:100%;height:auto;display:block}
.facts{margin:0;display:grid;gap:12px}
.fact dt{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.18em;
  font-size:10.5px;color:var(--gold);font-weight:600}
.fact dd{margin:1px 0 0;font-family:"Barlow Condensed",var(--cjk-sans);font-weight:500;font-size:17px;line-height:1.2}
.fact dd small{display:block;font-family:"Barlow",var(--cjk-sans);font-weight:400;font-size:12.5px;
  color:var(--muted);margin-top:2px;line-height:1.35}
.fact dd a{color:var(--slate-ink);text-decoration:none;border-bottom:1px solid rgba(110,138,166,.4)}
.countdown{display:inline-flex;align-items:center;gap:7px;margin-top:2px;
  font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.12em;
  font-size:11.5px;color:var(--sage);font-weight:600}
.countdown i{width:6px;height:6px;border-radius:50%;background:var(--sage);font-style:normal}
.countdown.soon{color:var(--coral)} .countdown.soon i{background:var(--coral)}

/* ---------------- card ---------------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:26px 22px;box-shadow:var(--shadow);position:relative;overflow:hidden}
.card .ghostmark{position:absolute;right:-40px;bottom:-56px;width:230px;opacity:.055;pointer-events:none}
.card>*{position:relative}
h2{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.12em;
  font-size:16px;margin:0;color:var(--slate-ink);font-weight:600}
.lede{margin:6px 0 22px;color:var(--muted);font-size:14.5px}

fieldset{border:0;margin:0 0 22px;padding:0}
legend,.lab{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.12em;
  font-size:12px;font-weight:600;color:var(--slate-ink);padding:0;margin-bottom:8px;display:block}
.hint{font-family:"Barlow",var(--cjk-sans);text-transform:none;letter-spacing:0;color:var(--muted);
  font-weight:400;font-size:12px}
.field{margin-bottom:22px}
input[type=text],input[type=email],input[type=tel],input[type=password],
input[type=datetime-local],textarea,select{
  width:100%;min-height:var(--tap);padding:12px 14px;font:inherit;font-size:16px;color:var(--ink);
  background:#fff;border:1.5px solid var(--line);border-radius:10px;outline:none;
  transition:border-color .16s,box-shadow .16s}
textarea{resize:vertical;line-height:1.5;min-height:96px}
input::placeholder,textarea::placeholder{color:#AEB5BC}
input:focus,textarea:focus,select:focus{border-color:var(--slate);box-shadow:0 0 0 4px rgba(110,138,166,.15)}
[aria-invalid=true]{border-color:var(--coral)!important;background:#FFF9F7}
.err{color:var(--coral);font-size:13px;margin-top:6px;display:flex;gap:6px;align-items:flex-start}
.err:empty{display:none}
.err::before{content:"!";flex:none;width:15px;height:15px;border-radius:50%;background:var(--coral);
  color:#fff;font-size:10.5px;font-weight:700;display:grid;place-items:center;margin-top:2px;font-family:"Barlow",var(--cjk-sans)}

/* segmented choices */
.choice{display:grid;gap:10px}
.choice.two{grid-template-columns:1fr 1fr}
.choice.three{grid-template-columns:repeat(3,1fr)}
.choice input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.choice label{display:flex;align-items:center;justify-content:center;margin:0;min-height:var(--tap);
  padding:12px 8px;border:1.5px solid var(--line);border-radius:11px;background:#fff;cursor:pointer;
  font-family:"Barlow Condensed",var(--cjk-sans);font-size:14px;font-weight:500;letter-spacing:.06em;
  text-align:center;line-height:1.15;text-transform:none;color:var(--ink);
  transition:background .16s,border-color .16s,color .16s}
.choice label:hover{border-color:var(--slate)}
.choice input:checked+label{background:var(--slate);border-color:var(--slate);color:#fff;font-weight:600}
.choice input:focus-visible+label{outline:2.5px solid var(--slate);outline-offset:3px}
.choice .tick{width:0;height:16px;flex:none;opacity:0;margin-right:0;overflow:visible;
  transition:width .16s ease,margin .16s ease,opacity .16s ease}
.choice input:checked+label .tick{width:16px;margin-right:7px;opacity:1}

/* additional pax — two dropdowns abreast, stacked where that would crowd */
.pax{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.pax .field{margin-bottom:0}
fieldset>.hint{margin:-4px 0 10px}
@media(max-width:420px){.pax{grid-template-columns:1fr}}

/* reveal */
.reveal{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .34s ease,opacity .24s ease}
.reveal>div{overflow:hidden;min-height:0}
.reveal.open{grid-template-rows:1fr;opacity:1}
.reveal-head{display:flex;align-items:center;gap:10px;margin-bottom:18px;color:var(--sage);
  font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.14em;font-size:11px;font-weight:600}
.reveal-head::after{content:"";flex:1;height:1px;background:var(--line-soft)}

/* buttons */
button{font:inherit}
.btn{width:100%;min-height:52px;border:0;border-radius:12px;background:var(--gold);color:#FFFAF0;
  text-decoration:none;text-align:center;padding:14px 18px;box-sizing:border-box;
  font-family:"Barlow Condensed",var(--cjk-sans);font-size:17px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;cursor:pointer;transition:background .16s,transform .08s;
  display:flex;align-items:center;justify-content:center;gap:10px}
.btn:hover{background:var(--gold-deep)}
.btn:active{transform:translateY(1px)}
.btn[disabled]{opacity:.6;cursor:not-allowed;transform:none}
.btn.quiet{background:transparent;color:var(--slate-ink);border:1.5px solid var(--line);font-size:14px}
.btn.quiet:hover{border-color:var(--slate);background:rgba(110,138,166,.06)}
.ghost{background:none;border:1.5px solid var(--line);color:var(--slate-ink);border-radius:10px;
  min-height:42px;padding:0 16px;font-family:"Barlow Condensed",var(--cjk-sans);letter-spacing:.1em;
  text-transform:uppercase;font-size:12.5px;font-weight:600;cursor:pointer;transition:.16s}
.ghost:hover{border-color:var(--slate);color:var(--slate-ink);background:rgba(110,138,166,.07)}
.spin{width:15px;height:15px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;
  animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------------- the host's note ---------------- */
/* Quieter than the reply form beside it — it is something to read, not to do. */
.card.note{padding:20px 22px;margin-bottom:20px;
  background:linear-gradient(var(--card),var(--card)) padding-box,
             linear-gradient(160deg,rgba(169,133,70,.35),rgba(143,168,141,.3)) border-box;
  border:1px solid transparent;box-shadow:none}
.card.note h2{color:var(--gold-deep)}
.card.note p{margin:8px 0 0;font-size:14.5px;line-height:1.6;color:var(--ink)}

/* the same note, tucked inside the confirmation card */
.note.inline{margin:20px 0 0;padding:16px 18px;border-radius:12px;text-align:left;
  background:rgba(169,133,70,.07);border:1px solid rgba(169,133,70,.18)}
.note.inline h3{margin:0;font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;
  letter-spacing:.12em;font-size:11.5px;font-weight:600;color:var(--gold-deep)}
.note.inline p{margin:6px 0 0;font-size:14px;line-height:1.6;text-align:left}

.footnote{text-align:center;margin-top:24px;font-family:"Barlow Condensed",var(--cjk-sans);
  letter-spacing:.12em;text-transform:uppercase;font-size:11.5px;color:var(--muted)}
.footnote a{color:var(--muted);text-decoration:none;border-bottom:1px dotted currentColor;padding:6px 2px}

/* ---------------- confirmation ---------------- */
.done{text-align:center}
.done .mark{width:62px;height:62px;border-radius:50%;display:grid;place-items:center;margin:2px auto 16px;
  background:rgba(143,168,141,.18);color:#5F7B5D;animation:pop .45s cubic-bezier(.2,1.4,.4,1)}
.done .mark.soft{background:rgba(169,133,70,.15);color:var(--gold-deep)}
@keyframes pop{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}
.done h2{font-size:23px;letter-spacing:.05em;color:var(--gold)}
.summary{text-align:left;margin:20px 0 0;border-top:1px solid var(--line-soft)}
.summary div{display:flex;justify-content:space-between;gap:18px;padding:11px 2px;border-bottom:1px solid var(--line-soft)}
.summary dt{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.12em;
  font-size:11.5px;color:var(--muted);margin:0}
.summary dd{margin:0;text-align:right;font-weight:500;font-size:14.5px}
.actions{display:grid;gap:10px;margin-top:22px}
@media(min-width:440px){.actions.two{grid-template-columns:1fr 1fr}}

/* the number from step one, shown rather than re-asked */
.field.locked .fixed{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin:0;min-height:var(--tap);padding:12px 14px;border-radius:10px;
  background:rgba(110,138,166,.07);border:1.5px solid var(--line)}
.field.locked .fixed strong{font-size:16px;font-weight:600;letter-spacing:.01em}
.linkbtn{background:none;border:0;padding:0;font:inherit;font-size:13px;color:var(--slate);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer;min-height:auto}
.linkbtn:hover{color:var(--slate-ink)}

/* returning guest banner */
.banner{display:flex;gap:12px;align-items:flex-start;background:rgba(143,168,141,.12);
  border:1px solid rgba(143,168,141,.35);border-radius:12px;padding:14px 16px;margin-bottom:20px}
.banner p{margin:0;font-size:14px}
.banner strong{font-family:"Barlow Condensed",var(--cjk-sans);letter-spacing:.06em;display:block;font-size:15px}

/* ---------------- admin ---------------- */
.adminbar{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  margin-bottom:22px;flex-wrap:wrap}
.adminbar h1{font-family:"Barlow Condensed",var(--cjk-sans);font-size:34px;font-weight:600;margin:.08em 0 0;
  color:var(--slate-ink);letter-spacing:.01em;text-transform:uppercase}
.adminbar .eyebrow{font-size:18px}
.adminbar .tools-r{display:flex;gap:8px;flex-wrap:wrap}

.stats{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:12px}
@media(min-width:720px){.stats{grid-template-columns:repeat(4,1fr)}}
.stat{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:15px 16px;box-shadow:var(--shadow)}
.stat .n{font-family:"Barlow Condensed",var(--cjk-sans);font-size:clamp(28px,7vw,38px);font-weight:600;
  line-height:1;color:var(--slate-ink)}
.stat .l{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.13em;
  font-size:10.5px;color:var(--muted);margin-top:6px}
.stat.sage .n{color:#5F7B5D}.stat.coral .n{color:var(--coral)}

.catering{background:var(--card);border:1px solid var(--line);border-radius:13px;padding:16px;
  margin-bottom:20px;box-shadow:var(--shadow)}
.catering h3{margin:0 0 12px;font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;
  letter-spacing:.14em;font-size:11.5px;color:var(--muted);font-weight:600}
.bar{display:flex;align-items:center;gap:12px;margin-bottom:10px;font-size:14px}
.bar:last-child{margin-bottom:0}
.bar .k{flex:none;width:104px;font-family:"Barlow Condensed",var(--cjk-sans);letter-spacing:.06em;font-size:13.5px}
.bar .track{flex:1;height:9px;background:rgba(35,46,56,.07);border-radius:99px;overflow:hidden}
.bar .fill{display:block;height:100%;border-radius:99px;transition:width .5s ease}
.bar .v{flex:none;width:30px;text-align:right;font-family:"Barlow Condensed",var(--cjk-sans);font-weight:600;font-size:15px}

.tools{display:flex;gap:10px;margin-bottom:14px;flex-wrap:wrap}
.tools .search{flex:1;min-width:200px;position:relative}
.tools .search input{padding-left:40px}
.tools .search svg{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--muted)}
.tools select{width:auto;min-width:158px;-webkit-appearance:none;appearance:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' fill='none' stroke='%23717C86' stroke-width='1.6' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 14px center;padding-right:36px}

/* No overflow clipping here on purpose. The tag picker hangs out of this card,
   and `overflow:hidden` would not only cut it off — it would make the card a
   scroll container, which the browser then scrolls to bring the focused picker
   into view, carrying the rows up out of sight. The corners are rounded on the
   table's own edge cells instead, so the header tint and the row hover still
   follow the card's shape. */
.tablecard{background:var(--card);border:1px solid var(--line);border-radius:13px;box-shadow:var(--shadow)}
thead tr:first-child th:first-child{border-top-left-radius:12px}
thead tr:first-child th:last-child{border-top-right-radius:12px}
tbody tr:last-child td:first-child{border-bottom-left-radius:12px}
tbody tr:last-child td:last-child{border-bottom-right-radius:12px}
/* separate, not collapse: a collapsed table ignores border-radius on its
   cells, and the cells are what round the card's corners now. The spacing
   is zeroed, so the single bottom borders below still read as one line. */
table{width:100%;border-collapse:separate;border-spacing:0;font-size:14.5px}
th{font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.13em;font-size:10.5px;
  color:var(--muted);text-align:left;padding:13px 16px;border-bottom:1px solid var(--line);white-space:nowrap;
  background:rgba(35,46,56,.02)}
th button{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer;
  display:inline-flex;align-items:center;gap:5px;text-transform:inherit;letter-spacing:inherit}
th button:hover{color:var(--slate-ink)}
th .arrow{opacity:.35;font-size:9px}
th[aria-sort] button{color:var(--slate-ink)} th[aria-sort] .arrow{opacity:1}
td{padding:13px 16px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:rgba(110,138,166,.045)}
td a{color:var(--slate-ink);text-decoration:none;border-bottom:1px solid rgba(110,138,166,.3)}
.who strong{display:block;font-weight:600}
.who span{color:var(--muted);font-size:12px}
.pill{display:inline-flex;align-items:center;gap:5px;padding:4px 11px;border-radius:99px;font-size:11.5px;
  font-weight:600;font-family:"Barlow Condensed",var(--cjk-sans);letter-spacing:.09em;text-transform:uppercase}
.pill.yes{background:rgba(143,168,141,.25);color:#4F6B4D}
.pill.no{background:rgba(204,112,89,.18);color:#9E4E38}
.pill.diet{background:rgba(110,138,166,.16);color:var(--slate-ink)}
.pill.diet.veg{background:rgba(143,168,141,.22);color:#4F6B4D}
.pill.diet.halal{background:rgba(169,133,70,.2);color:var(--gold-deep)}
.rowbtn{border:0;background:none;color:var(--muted);cursor:pointer;padding:8px;border-radius:8px;line-height:0}
.rowbtn:hover{color:var(--coral);background:rgba(204,112,89,.1)}
.confirm{display:inline-flex;gap:6px;align-items:center;font-size:12px;color:var(--coral);
  font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.08em}
.confirm button{border:0;background:none;cursor:pointer;font:inherit;text-decoration:underline;color:inherit;padding:6px 2px}
.confirm button.keep{color:var(--muted)}

/* tags */
.tagpanel h3{display:flex;align-items:center;justify-content:space-between;gap:12px}
.linkish{border:0;background:none;padding:0;cursor:pointer;font:inherit;color:var(--slate-ink);
  font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;letter-spacing:.12em;
  font-size:10.5px;text-decoration:underline}
.tagempty{margin:0;font-size:13.5px;color:var(--muted)}

/* the invitation's own details, read back the way a guest sees them */
.bar.readout{align-items:flex-start}
.bar.readout .v-wide{flex:1;font-family:"Barlow Condensed",var(--cjk-sans);font-weight:500;
  font-size:15px;line-height:1.25;text-align:left;min-width:0;overflow-wrap:anywhere}
.bar.readout .v-wide small{display:block;font-family:"Barlow",var(--cjk-sans);font-weight:400;
  font-size:12.5px;color:var(--muted);margin-top:2px;line-height:1.4;white-space:pre-line}
.eventedit{margin-top:14px;padding-top:14px;border-top:1px solid var(--line-soft)}
.eventedit .field{margin-bottom:14px}
.eventedit .pair{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
@media (max-width:560px){.eventedit .pair{grid-template-columns:1fr}}
.eventedit .tagempty{margin:0 0 14px}

.tagmanage{margin-top:14px;padding-top:14px;border-top:1px solid var(--line-soft);
  display:flex;flex-direction:column;gap:8px}
.tagrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tagrow input[type=text]{flex:1;min-width:140px}
.tagrow select{width:auto;min-width:104px}
.tagrow.add{margin-top:2px;padding-top:10px;border-top:1px dashed var(--line-soft)}

.pill.tag{gap:4px;padding-right:7px;margin:2px 4px 2px 0}
.pill.tag.slate{background:rgba(110,138,166,.16);color:var(--slate-ink)}
.pill.tag.sage{background:rgba(143,168,141,.22);color:#4F6B4D}
.pill.tag.gold{background:rgba(169,133,70,.2);color:var(--gold-deep)}
.pill.tag.coral{background:rgba(204,112,89,.18);color:#9E4E38}
.pill.tag button{border:0;background:none;color:inherit;cursor:pointer;font:inherit;
  line-height:1;padding:0 1px;opacity:.5}
.pill.tag button:hover{opacity:1}

/* the picker hangs off this cell, so it anchors the absolute positioning */
.tagcell{position:relative;min-width:132px}
.tagadd{border:1px dashed var(--line);background:none;color:var(--muted);cursor:pointer;
  border-radius:99px;width:24px;height:24px;padding:0;line-height:1;font-size:15px;vertical-align:middle}
.tagadd:hover{color:var(--slate-ink);border-color:var(--slate)}

.tagpick{position:absolute;z-index:20;top:calc(100% + 6px);left:0;width:250px;padding:10px;
  text-align:left;background:var(--card);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 14px 34px -14px rgba(35,46,56,.45)}
.tagpick input[type=text]{margin-bottom:8px}
.tagpick .ghost{width:100%}
.tagopts{display:flex;flex-direction:column;gap:2px;max-height:190px;overflow-y:auto;margin-bottom:8px}
.tagopts button{display:flex;align-items:center;gap:8px;width:100%;text-align:left;border:0;
  background:none;cursor:pointer;font:inherit;font-size:14px;padding:7px 8px;border-radius:8px;color:var(--ink)}
.tagopts button:hover{background:rgba(110,138,166,.09)}
.tagopts button.on{color:var(--slate-ink);font-weight:600}
.tagopts .dot{flex:none;width:9px;height:9px;border-radius:50%}
.tagopts .tick{flex:none;width:14px;height:14px;margin-left:auto;color:var(--sage)}
.tagopts .make{color:var(--gold-deep)}

.state{padding:52px 24px;text-align:center;color:var(--muted);font-size:14px}
.state svg{width:56px;opacity:.3;margin-bottom:14px}
.state strong{display:block;font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;
  letter-spacing:.13em;color:var(--slate-ink);margin-bottom:7px;font-size:14px}
.notice{font-size:12.5px;color:var(--muted);margin-top:16px;line-height:1.55}

/* admin table → cards on small screens */
@media(max-width:760px){
  thead{position:absolute;left:-9999px}
  tbody tr{display:block;padding:14px 16px;border-bottom:1px solid var(--line)}
  tbody tr:last-child{border-bottom:0}
  td{display:flex;justify-content:space-between;gap:16px;padding:5px 0;border:0;text-align:right}
  td::before{content:attr(data-l);font-family:"Barlow Condensed",var(--cjk-sans);text-transform:uppercase;
    letter-spacing:.12em;font-size:10.5px;color:var(--muted);flex:none;padding-top:3px}
  td.who{padding-bottom:8px}
  td.who::before{display:none}
  td.who strong{font-size:16px}
  .who{text-align:left;display:block}
  tbody tr:last-child td{border-radius:0}
  tbody tr:last-child{border-bottom-left-radius:12px;border-bottom-right-radius:12px}
  td.tagcell{flex-wrap:wrap;justify-content:flex-end}
  .tagpick{position:static;width:100%;margin-top:8px}
}

/* toast */
#toast{position:fixed;left:50%;bottom:calc(24px + env(safe-area-inset-bottom));transform:translate(-50%,20px);
  background:var(--ink);color:#F7F4EC;padding:12px 20px;border-radius:99px;font-size:14px;z-index:60;
  opacity:0;pointer-events:none;transition:opacity .22s,transform .22s;box-shadow:0 10px 30px rgba(0,0,0,.2)}
#toast.show{opacity:1;transform:translate(-50%,0)}

.gate{max-width:380px;margin:6vh auto 0}
.loading{padding:64px 20px;text-align:center;color:var(--muted);font-size:14px}

/* ---------------- motion (invitation page only) ---------------- */
@keyframes rise{from{opacity:0;transform:translateY(12px)}}
@keyframes slidein{from{opacity:0;transform:translateY(-6px)}}
@keyframes drift{from{transform:translate3d(0,0,0) scale(1)}
                 to{transform:translate3d(-1.5%,1.6%,0) scale(1.06)}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@keyframes ping{0%{box-shadow:0 0 0 0 color-mix(in srgb,currentColor 55%,transparent)}
                70%,100%{box-shadow:0 0 0 7px transparent}}
@keyframes sheen{from{transform:translateX(-160%) skewX(-18deg)}
                 to{transform:translateX(240%) skewX(-18deg)}}
@keyframes settle{from{transform:scale(.97)}}
@keyframes ringout{from{box-shadow:0 0 0 0 rgba(143,168,141,.5)}to{box-shadow:0 0 0 20px rgba(143,168,141,0)}}
@keyframes ringout-soft{from{box-shadow:0 0 0 0 rgba(169,133,70,.45)}to{box-shadow:0 0 0 20px rgba(169,133,70,0)}}

/* the watercolour wash drifts, slowly enough that you only notice it if you look for it.
   the oversized inset keeps an edge from sliding into view at the extremes. */
body.guest::after{inset:-15%;will-change:transform;animation:drift 44s var(--ease) infinite alternate}

/* each section rises into place as the page paints. every screen is re-injected as
   innerHTML, so this replays on submit and on "change my reply" without any wiring. */
body.guest #app>*{animation:rise .55s var(--ease-out) both}
body.guest #app>*:nth-child(1){animation-delay:.02s}
body.guest #app>*:nth-child(2){animation-delay:.1s}
body.guest #app>*:nth-child(3){animation-delay:.18s}
body.guest #app>*:nth-child(4){animation-delay:.26s}
/* five when the host has left a note, four when they have not */
body.guest #app>*:nth-child(5){animation-delay:.34s}
body.guest .banner{animation:slidein .4s var(--ease-out) .42s both}

/* the ribbon catches the light once, after the entrance has settled */
body.guest .ribbon{position:relative;overflow:hidden}
body.guest .ribbon::after{content:"";position:absolute;top:0;bottom:0;left:0;width:40%;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,250,240,.5),transparent);
  animation:sheen 1.5s var(--ease) .9s 1 both}

/* the three accent dots on the numeral drift out of step with each other */
body.guest .hero svg circle{animation:bob 8s var(--ease) infinite}
body.guest .hero svg circle:nth-of-type(2){animation-duration:9.5s;animation-delay:-3s}
body.guest .hero svg circle:nth-of-type(3){animation-duration:7s;animation-delay:-5.5s}

/* the countdown dot pulses in whichever colour .soon has settled on */
body.guest .countdown i{animation:ping 2.8s var(--ease) infinite}
body.guest .countdown.soon i{animation-duration:1.9s}

body.guest input[type=text],body.guest input[type=email],body.guest input[type=tel],body.guest select{
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}

body.guest .choice label{
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),
    color var(--dur) var(--ease),transform var(--dur) var(--ease),box-shadow var(--dur) var(--ease)}
body.guest .choice label:hover{transform:translateY(-1px);box-shadow:0 4px 12px -8px rgba(35,46,56,.45)}
body.guest .choice input:checked+label{animation:settle .28s var(--ease-out)}

/* buttons lift and glow; the primary one catches a sheen as the pointer crosses it.
   the sheen is absolutely positioned because .btn is a flex row — a static
   pseudo-element would join the flow and push the label off centre. */
body.guest .btn{position:relative;overflow:hidden;
  transition:background var(--dur) var(--ease),transform var(--dur) var(--ease),
    box-shadow .28s var(--ease),border-color var(--dur) var(--ease)}
body.guest .btn:not(.quiet)::after{content:"";position:absolute;top:0;bottom:0;left:0;width:45%;
  pointer-events:none;transform:translateX(-160%) skewX(-18deg);
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.3),transparent)}
body.guest .btn:not(.quiet):hover::after{animation:sheen .75s var(--ease) 1}
body.guest .btn:hover{transform:translateY(-1px);box-shadow:0 6px 18px -6px rgba(169,133,70,.5)}
body.guest .btn.quiet:hover{transform:translateY(-1px);box-shadow:0 5px 16px -8px rgba(66,96,126,.45)}
body.guest .btn:active{transform:translateY(1px);box-shadow:none;transition-duration:.06s}
body.guest .btn[disabled],body.guest .btn[disabled]:hover,body.guest .btn[disabled]:active{
  transform:none;box-shadow:none}
body.guest .btn[disabled]::after{display:none}

/* the confirmation badge keeps its pop and gains a ring that expands away behind it */
body.guest .done .mark{position:relative}
body.guest .done .mark::after{content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;
  animation:ringout .9s var(--ease-out) .12s both}
body.guest .done .mark.soft::after{animation-name:ringout-soft}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;
    animation-iteration-count:1!important;transition-duration:.01ms!important}
}
