/* BrideHub SA — the brand, as CSS. Same palette and faces as the prototype. */

/* Anything carrying the hidden attribute is hidden. Full stop.
   The browser's own rule for this is display:none, and ANY rule in this file
   that sets display on the same element beats it — because an author sheet
   always outranks the browser's. That is how ".shell{display:grid}" quietly
   cancelled hidden on the signed-in shell: signing out showed the sign-in card
   with the whole dashboard still sitting underneath it, somebody else's data
   left on screen on a shared phone. One line, and no rule added later can do
   it again. */
[hidden]{display:none!important}

:root{
  color-scheme:light;
  --paper:#FBF4F2; --surface:#FFFFFF; --surface-2:#F6EAE7;
  --ink:#1B2A4A; --ink-2:#5D6A87; --ink-3:#8C97AD;
  --line:#EBDCD8; --line-2:#DFCEC9;
  --rose:#C4737F; --rose-soft:#FAEAEC;
  --gold:#B08A38;
  --good:#2F7A5B; --good-soft:#E2F1EA;
  --stop:#A94236; --stop-soft:#FAE7E4;
  --gold-soft:#F6ECD6;
  --warn:#B4632F; --warn-soft:#FAEADF;
  --display:"Cormorant Garamond",Georgia,serif;
  --ui:"Karla","Helvetica Neue",Arial,sans-serif;
}
@media (prefers-color-scheme:dark){:root{
  color-scheme:dark;
  --paper:#141A2B; --surface:#1C2338; --surface-2:#252E48;
  --ink:#F3E9E8; --ink-2:#AEB8CF; --ink-3:#7E89A4;
  --line:#2E3853; --line-2:#3B4665;
  --rose:#E9A3AD; --rose-soft:#33222A;
  --gold:#D8B45F;
  --good:#6DC5A0; --good-soft:#1B3129;
  --stop:#E4897C; --stop-soft:#33211E;
  --gold-soft:#3A3120;
  --warn:#E3A277; --warn-soft:#35261C;
}}

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--ui);
  font-size:15.5px;line-height:1.6;-webkit-font-smoothing:antialiased;
  display:flex;flex-direction:column;min-height:100vh}

/* ---------- chrome ---------- */
/* Always on screen. Sign out, whose wedding this is, and the way back to the
   top were all a long scroll away on a phone. */
.top{display:flex;align-items:center;gap:16px;padding:0 20px;height:60px;
  background:var(--surface);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:40;flex:none}
.brand{font-family:var(--display);font-size:25px;font-weight:600;color:var(--ink)}
.brand em{font-style:normal;color:var(--rose)}
.brand span{font-family:var(--ui);font-size:9.5px;font-weight:700;letter-spacing:.18em;
  color:var(--gold);vertical-align:6px;margin-left:5px}
.sp{flex:1}

.wrap{flex:1;width:100%;max-width:640px;margin:0 auto;padding:34px 20px 60px}
h1{font-family:var(--display);font-size:clamp(30px,6vw,40px);font-weight:600;
  line-height:1.1;margin:0 0 8px;text-wrap:balance}
h2{font-family:var(--display);font-size:22px;font-weight:600;margin:0 0 6px}
.stand{color:var(--ink-2);margin:0 0 24px;max-width:52ch}

.card{background:var(--surface);border:1px solid var(--line);border-radius:14px;
  padding:22px;margin-bottom:18px}
.card.proof{background:none;border-style:dashed}
.card.proof p{font-size:14px;color:var(--ink-2);margin:0 0 8px}

/* ---------- tabs ---------- */
.tabs{display:flex;gap:4px;background:var(--surface-2);border-radius:10px;
  padding:4px;margin-bottom:20px}
.tabs button{flex:1;border:0;background:none;color:var(--ink-2);font:inherit;
  font-size:14px;font-weight:600;padding:8px 10px;border-radius:7px;cursor:pointer}
.tabs button.on{background:var(--surface);color:var(--ink);
  box-shadow:0 1px 3px rgba(0,0,0,.08)}

/* ---------- forms ---------- */
.fld{margin-bottom:16px}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:480px){.frow{grid-template-columns:1fr;gap:0}}
.fl{display:block;font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700;margin-bottom:6px}
input{width:100%;font:inherit;font-size:15px;color:var(--ink);background:var(--surface);
  border:1px solid var(--line-2);border-radius:9px;padding:10px 12px}
input[type=date]{max-width:220px}
input:focus{outline:2px solid var(--rose);outline-offset:1px;border-color:var(--rose)}
/* A cap on the line length, not on the card. Cards full of rows and swatches
   are better wide; a sentence of explanation is not — past about eighty
   characters the eye loses its place coming back to the left. */
.note{font-size:12.5px;color:var(--ink-3);margin:6px 0 0;max-width:78ch}

.btn{background:var(--rose);color:#fff;border:0;border-radius:9px;
  padding:11px 20px;font:inherit;font-size:15px;font-weight:600;cursor:pointer}
.btn:hover:not(:disabled){filter:brightness(1.05)}
.btn:disabled{opacity:.6;cursor:default}
.ghost{background:none;border:1px solid var(--line-2);color:var(--ink-2);
  border-radius:8px;padding:7px 13px;font:inherit;font-size:13px;cursor:pointer}
.ghost:hover{border-color:var(--rose);color:var(--rose)}
/* A button that reads as a link. Deliberately quiet — it is only wanted on
   the day something has gone wrong. */
.linky{display:block;margin:14px auto 0;background:none;border:0;padding:4px;
  font:inherit;font-size:13.5px;color:var(--ink-2);text-decoration:underline;
  text-underline-offset:3px;cursor:pointer}
.linky:hover{color:var(--rose)}
.linky[hidden]{display:none}

/* ---------- messages ---------- */
.msg{font-size:14px;border-radius:9px;padding:10px 13px;margin:0 0 16px}
.msg.good{background:var(--good-soft);color:var(--good)}
.msg.bad{background:var(--stop-soft);color:var(--stop)}
.banner{padding:12px 20px;font-size:14px;text-align:center}
.banner.bad{background:var(--stop-soft);color:var(--stop);
  border-bottom:1px solid var(--stop)}

.foot{padding:20px;text-align:center;font-size:12.5px;color:var(--ink-3);
  border-top:1px solid var(--line)}
.foot .dot{margin:0 6px}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ============================================================
   The app shell — added when the bare test form became BrideHub
   ============================================================ */

/* The logo's ring is drawn in rose; its other two groups pick up --ink and
   --gold, so the mark re-colours itself in dark mode along with everything
   else rather than needing a second copy. */
:root{ --logo-ring:var(--rose) }

.mark{width:34px;height:34px;flex:0 0 34px;display:flex;align-items:center;justify-content:center}
.mark .logo{width:100%;height:100%;display:block}
.top{gap:10px}
.brand{white-space:nowrap}

/* ---------- the couple, in the top bar ---------- */
.whoami{display:flex;align-items:center;gap:9px;margin-left:8px;padding:4px 10px 4px 4px;
  background:none;border:1px solid transparent;border-radius:999px;font:inherit;
  color:inherit;cursor:pointer;text-align:left;max-width:min(46vw,320px)}
.whoami:hover{border-color:var(--line-2);background:var(--surface-2)}
.whoami .wpic{width:32px;height:32px;flex:0 0 32px;border-radius:50%;
  background:var(--surface-2);border:1.5px solid var(--rose);
  background-size:cover;background-position:50% 50%;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:700;color:var(--rose);letter-spacing:.02em}
.whoami .wtxt{min-width:0;display:flex;flex-direction:column;line-height:1.25}
.whoami .wtxt b{font-size:13.5px;font-weight:700;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.whoami .wtxt small{font-size:11px;color:var(--ink-3);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* ---------- the two small buttons on the ribbon ----------
   The gear and the way out to their own wedding page. Icon only: a word beside
   either of them would crowd the bar on a phone, and both carry a title and an
   aria-label so nothing depends on recognising a picture. 40px square, which
   is a comfortable target for a thumb. */
.ribbtn{width:40px;height:40px;flex:0 0 40px;display:flex;align-items:center;
  justify-content:center;padding:0;border-radius:999px;cursor:pointer;
  background:none;border:1px solid transparent;color:var(--ink-2)}
.ribbtn svg{width:20px;height:20px;display:block}
.ribbtn:hover{border-color:var(--line-2);background:var(--surface-2);color:var(--ink)}
.ribbtn:focus-visible{outline:2px solid var(--rose);outline-offset:2px}
.ribbtn.on{color:var(--rose);border-color:var(--line-2);background:var(--surface-2)}

/* The wedding website, which keeps its words. It is the one section couples
   jump back to from everywhere else, and a picture on its own would make
   people guess. */
.ribword{display:flex;align-items:center;gap:8px;height:40px;padding:0 13px;
  border-radius:999px;cursor:pointer;font:inherit;font-size:13.5px;font-weight:600;
  background:none;border:1px solid var(--line-2);color:var(--ink-2);white-space:nowrap}
.ribword svg{width:17px;height:17px;flex:0 0 17px}
.ribword:hover{background:var(--surface-2);color:var(--ink)}
.ribword:focus-visible{outline:2px solid var(--rose);outline-offset:2px}
.ribword.on{color:var(--rose);border-color:var(--rose);background:var(--surface-2)}

/* ---------- shell ----------
   The menu sits against the left edge of the window rather than inside a
   centred column, so the working area gets the whole of the rest — which is
   what the wedding website's preview needs to be worth looking at. */
.shell{flex:1;display:grid;grid-template-columns:242px minmax(0,1fr);
  align-items:start;width:100%}

/* Tucked is a narrow rail, not a hidden menu: every icon stays clickable, so
   tidying the screen can never make a section unreachable. */
.shell.tuck{grid-template-columns:60px minmax(0,1fr)}
.shell.tuck #nav{padding:20px 10px}
.shell.tuck .lbl2{display:none}
.shell.tuck #navlinks button{justify-content:center;padding:10px 0;gap:0}
/* No room for a word on a 60px rail, and the icon is the point. The button
   keeps its title, so hovering still says "Guest album — coming soon". */
.shell.tuck #navlinks .pip{display:none}
/* The chevron sits astride the rail's edge, which puts it over the first icon
   once the rail is narrow. Give the icons their own row beneath it. */
.shell.tuck #navlinks{margin-top:30px}

/* 60px, because that is where the top bar now stops. The rail reaches the
   bottom edge of the window for the same reason the preview does. */
#nav{position:sticky;top:60px;padding:20px 12px 40px;border-right:1px solid var(--line);
  min-height:calc(100vh - 60px)}
.navtog{position:absolute;right:-17px;top:22px;z-index:20;
  width:34px;height:34px;padding:0;line-height:0;cursor:pointer;
  background:var(--surface);border:1px solid var(--line-2);color:var(--ink-2);
  border-radius:99px;display:grid;place-items:center;box-shadow:0 1px 4px rgba(0,0,0,.1)}
.navtog:hover{border-color:var(--rose);color:var(--rose)}
.navtog svg{display:block}

#navlinks{display:flex;flex-direction:column;gap:2px}
#navlinks button{display:flex;align-items:center;gap:10px;width:100%;position:relative;
  background:none;border:0;border-radius:9px;padding:9px 12px;font:inherit;
  font-size:14px;font-weight:500;color:var(--ink-2);cursor:pointer;text-align:left}
.ico{flex:none;width:20px;height:20px;display:block}
.ico svg{width:100%;height:100%;display:block}
.lbl2{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#navlinks button:hover:not(:disabled){background:var(--surface-2);color:var(--ink)}
#navlinks button.on{background:var(--surface);color:var(--ink);font-weight:700;
  box-shadow:0 1px 3px rgba(0,0,0,.07)}
#navlinks button.soon{color:var(--ink-3);cursor:default}
#navlinks .pip{margin-left:auto;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--gold);white-space:nowrap}
#navlinks button.on .pip{color:var(--rose)}

/* Wider than before, and centred in whatever space the menu leaves — so
   collapsing the menu gives the content more room and re-centres it, rather
   than opening a lopsided gap on the right. */
.view{min-width:0;padding:24px 30px 60px;max-width:1400px;margin:0 auto;width:100%}

/* The website editor takes the whole window: its right half is a picture of a
   page, and a picture of a page wants to be big. */
/* The preview runs to the bottom EDGE of the window, not to the top of the
   footer strip: 60 for the top bar, 24 above, 16 below, and nothing set aside
   for the footer. The footer is still there — it is simply below the fold, and
   a scroll brings it up, which is all anybody ever wants from it. */
.view:has(.split){max-width:none;padding-bottom:16px}

@media (max-width:860px){
  /* Plain stacked blocks rather than a grid. A sticky grid item can only move
     within its own row, and its row is exactly as tall as it is — which is why
     the menu strip scrolled away however sticky it was told to be. */
  .shell,.shell.tuck{display:block;grid-template-columns:1fr}
  /* The strip stays on screen under the bar rather than scrolling away behind
     it, and the air around it is halved — it was a menu's worth of padding on
     what is now a single row. */
  #nav,.shell.tuck #nav{position:sticky;top:60px;z-index:30;min-height:0;
    border-right:0;border-bottom:1px solid var(--line);padding:5px 14px;
    background:var(--paper)}
  .navtog{display:none}
  .shell.tuck .lbl2{display:block}
  .shell.tuck #navlinks button{justify-content:flex-start;padding:9px 12px;gap:10px}
  .shell.tuck #navlinks .pip{position:static}
  /* One strip that scrolls sideways, rather than a block of wrapped buttons
     that pushed the actual screen three rows down the page. Every section
     stays one tap away; you just slide to it. */
  #navlinks{flex-direction:row;flex-wrap:nowrap;gap:6px;
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
    scrollbar-width:none;-ms-overflow-style:none;
    /* the strip runs edge to edge, but the first and last buttons still get
       the same gutter as everything else on the screen */
    margin:0 -14px;padding:0 14px}
  #navlinks::-webkit-scrollbar{display:none}
  #navlinks button{width:auto;flex:0 0 auto;white-space:nowrap;
    scroll-snap-align:center;padding:9px 14px}
  #navlinks button{padding:8px 13px}
  .view{padding:20px 16px 50px}
}

/* ---------- dashboard ---------- */
.count{text-align:center;padding:30px 22px}
.count .big{font-family:var(--display);font-size:clamp(46px,13vw,76px);
  font-weight:600;line-height:1;color:var(--rose);display:block}
.count .cap{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700;margin-top:10px;display:block}
.count .when{font-size:15px;color:var(--ink-2);margin-top:14px}

/* The 1px gap IS the dividing line: the grid's own background shows through
   between cells. Drawing borders instead means guessing how many columns
   fitted, and the guess is wrong at every width but one. */
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:1px;background:var(--line);border-radius:13px;overflow:hidden}
.facts div{padding:13px 16px;background:var(--surface)}
.facts dt{font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}
.facts dd{margin:3px 0 0;font-size:15.5px}
.facts dd.none{color:var(--ink-3);font-style:italic}

.soonlist{margin:0;padding-left:20px;color:var(--ink-2);font-size:14.5px}
.soonlist li{margin:3px 0}

/* ---------- phone ----------
   This block used to carry a second, older copy of the menu rules — from when
   the shell was a flex column — and because it comes later in the file it was
   quietly undoing the ones above: position:static cancelled the sticky strip
   however many times it was set. The menu is handled once, at 860px; what is
   left here is only what is genuinely about a small screen. */
@media(max-width:760px){
  #navlinks button{font-size:13.5px}
  #navlinks .pip{margin-left:4px;font-size:8.5px;letter-spacing:.04em}
  .whoami .wtxt{display:none}
  .whoami{max-width:none;padding:4px}
}
/* Narrow enough that the words would push "Sign out" off the end. The button
   keeps its title and its aria-label, so hovering still says what it is and a
   screen reader still reads it out; only the printed words go. */
@media(max-width:620px){
  .ribword{width:40px;flex:0 0 40px;padding:0;justify-content:center}
  .ribword span{display:none}
}
@media(max-width:430px){
  .ribword{width:36px;flex:0 0 36px}
  .top{padding:0 13px;gap:7px}
  .brand{font-size:21px}
  .brand span{font-size:8.5px;margin-left:3px}
  .mark{width:28px;height:28px;flex:0 0 28px}
  /* Still a thumb-sized target; it just stops elbowing "Sign out" off the end. */
  .ribbtn{width:36px;height:36px;flex:0 0 36px}
  .ribbtn svg{width:19px;height:19px}
  /* Two more buttons on the bar left "Sign out" folded over two lines. It
     keeps its words — it is the one thing up here that should not be a
     picture — and gives up some padding instead. */
  .top #signout{white-space:nowrap;padding:8px 11px;font-size:13.5px}
}

/* Dropdowns are drawn by the browser; giving them the same skin as the text
   boxes keeps the profile from looking half-finished. The arrow is ours so it
   matches in dark mode too. */
select{width:100%;font:inherit;font-size:15px;color:var(--ink);
  background:var(--surface);border:1px solid var(--line-2);border-radius:9px;
  padding:10px 34px 10px 12px;appearance:none;-webkit-appearance:none;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 18px) 51%, calc(100% - 13px) 51%;
  background-size:5px 5px, 5px 5px;background-repeat:no-repeat}
select:focus{outline:2px solid var(--rose);outline-offset:1px;border-color:var(--rose)}

/* ---------- checklist ---------- */
.prog{height:7px;border-radius:99px;background:var(--surface-2);overflow:hidden;margin:2px 0 9px}
.prog span{display:block;height:100%;background:var(--rose);border-radius:99px;
  transition:width .25s ease}
@media (prefers-reduced-motion:reduce){.prog span{transition:none}}
.progtext{margin:0 0 14px;font-size:14px;color:var(--ink-2)}
.lateN{color:var(--stop);font-weight:700}

.stage{margin:0 0 20px}
.stage h3{font-family:var(--display);font-size:19px;font-weight:600;margin:0 0 8px;
  padding-left:2px}
.tasks{list-style:none;margin:0;padding:0;background:var(--surface);
  border:1px solid var(--line);border-radius:14px;overflow:hidden}
.task{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;
  border-top:1px solid var(--line)}
.task:first-child{border-top:0}

/* 26px is not decoration: it is about the smallest target a thumb hits
   reliably, and this is a list people tick on a phone. */
.tick{flex:0 0 auto;width:26px;height:26px;margin-top:1px;border-radius:8px;
  border:1.5px solid var(--line-2);background:var(--surface);color:#fff;
  font-size:15px;line-height:1;cursor:pointer;display:flex;
  align-items:center;justify-content:center}
.tick:hover{border-color:var(--rose)}
.task.done .tick{background:var(--rose);border-color:var(--rose)}

.tbody{flex:1;min-width:0;display:flex;flex-direction:column}
.ttitle{font-size:15px;line-height:1.4}
.tmeta{font-size:12px;color:var(--ink-3);margin-top:2px}
.task.done .ttitle{color:var(--ink-3);text-decoration:line-through}
.task.late .tmeta{color:var(--stop)}

.tact{flex:0 0 auto;display:flex;align-items:center;gap:6px}
.x{width:26px;height:26px;border:0;background:none;color:var(--ink-3);
  font-size:19px;line-height:1;border-radius:7px;cursor:pointer}
.x:hover{background:var(--stop-soft);color:var(--stop)}
.sure{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-2);
  white-space:nowrap}
.sure[hidden]{display:none}
.sure button{border:1px solid var(--line-2);background:var(--surface);font:inherit;
  font-size:12px;padding:4px 9px;border-radius:7px;cursor:pointer;color:var(--ink-2)}
.sure .yes{border-color:var(--stop);color:var(--stop)}

.soonlist.late li{color:var(--stop)}
.none{color:var(--ink-3);font-style:italic;padding:4px 2px 18px}
.card .ghost{margin-top:4px}

@media(max-width:430px){
  .sure{flex-direction:column;align-items:flex-end;gap:3px}
  .task{gap:9px;padding:11px 11px}
}

/* ---------- guest list ---------- */
.tally{display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:1px;
  background:var(--line);border-radius:12px;overflow:hidden;margin-bottom:12px}
.tally div{background:var(--surface);padding:11px 13px}
.tally dt{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}
.tally dd{margin:2px 0 0;font-family:var(--display);font-size:27px;font-weight:600;
  line-height:1.05}
.tally dd.good{color:var(--good)}

.stage h3 .hcount{font-family:var(--ui);font-size:11px;font-weight:700;color:var(--ink-3);
  background:var(--surface-2);border-radius:99px;padding:1px 8px;margin-left:7px;
  vertical-align:3px}

.guest{display:flex;align-items:center;gap:10px;padding:10px 14px;
  border-top:1px solid var(--line)}
.guest:first-child{border-top:0}
.guest.editing{display:block;padding:16px 14px;background:var(--surface-2)}
.gname{flex:1;min-width:0;display:flex;flex-direction:column;font-size:15px}
.gmeta{font-size:12px;color:var(--ink-3);margin-top:1px}

/* Three states, one tap each — faster than a dropdown when a couple is
   working through a stack of replies. */
.rsvpset{display:flex;gap:4px;flex:0 0 auto}
.rs{width:30px;height:30px;border-radius:8px;border:1.5px solid var(--line-2);
  background:var(--surface);color:var(--ink-3);font-size:14px;line-height:1;
  cursor:pointer;display:flex;align-items:center;justify-content:center}
.rs:hover{border-color:var(--rose)}
.rs.on.yes{background:var(--good);border-color:var(--good);color:#fff}
.rs.on.no{background:var(--stop);border-color:var(--stop);color:#fff}
.rs.on.pending{background:var(--gold);border-color:var(--gold);color:#fff}

.pencil{font-size:14px}
.gedit .fld{margin-bottom:12px}
.gbtns{display:flex;gap:8px;align-items:center}

@media(max-width:560px){
  .guest{flex-wrap:wrap;gap:8px}
  .gname{flex:1 1 100%}
  .rsvpset{margin-right:auto}
  .tally dd{font-size:23px}
}

/* ---------- budget ---------- */
.frow.three{grid-template-columns:repeat(3,1fr)}
@media(max-width:620px){.frow.three{grid-template-columns:1fr;gap:0}}

.tally dd.bad{color:var(--stop)}
.prog.over span{background:var(--stop)}

.bitem{display:flex;align-items:center;gap:12px;padding:11px 14px;
  border-top:1px solid var(--line)}
.bitem:first-child{border-top:0}
.bitem.editing{display:block;padding:16px 14px;background:var(--surface-2)}
.bmain{flex:1;min-width:0;display:flex;flex-direction:column}
.bname{font-size:15px}
.bmeta{font-size:12px;color:var(--ink-3);margin-top:1px}

/* Three figures, always in the same order and always aligned, so a column of
   them can be read down rather than hunted through. */
.bnums{display:flex;gap:16px;flex:0 0 auto;text-align:right}
.bn{display:flex;flex-direction:column;font-size:14px;font-variant-numeric:tabular-nums;
  min-width:74px}
.bn em{font-style:normal;font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}
.bn.owe{color:var(--ink)}

.stage h3 .hcount{font-variant-numeric:tabular-nums}

@media(max-width:620px){
  .bitem{flex-wrap:wrap;gap:8px}
  .bmain{flex:1 1 100%}
  .bnums{gap:14px;margin-right:auto;text-align:left}
  .bn{min-width:0}
}

/* ---------- seating chart ---------- */
.sech{font-family:var(--display);font-size:20px;font-weight:600;margin:22px 0 8px}
.sech .hcount{font-family:var(--ui);font-size:11px;font-weight:700;color:var(--ink-3);
  background:var(--surface-2);border-radius:99px;padding:1px 8px;margin-left:6px;
  vertical-align:3px}

.pool .hh{border-top:1px solid var(--line);padding:12px 0 4px}
.pool .hh:first-child{border-top:0;padding-top:0}
.hhead{display:flex;align-items:center;gap:10px;margin-bottom:7px}
.hhead b{font-size:13.5px}
.hhead .ghost{padding:4px 10px;font-size:12px}
.hhead .ghost.on{border-color:var(--rose);color:var(--rose);background:var(--rose-soft)}

.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{border:1px solid var(--line-2);background:var(--surface);color:var(--ink);
  font:inherit;font-size:13px;padding:5px 11px;border-radius:99px;cursor:pointer}
.chip:hover{border-color:var(--rose)}
.chip.on{background:var(--rose);border-color:var(--rose);color:#fff}
.chip em{font-style:normal;color:var(--gold);font-weight:700;margin-left:5px}
.chip.on em{color:#fff}
.chip.seated{background:var(--surface-2)}
.chip.seated:hover{border-color:var(--stop);color:var(--stop)}

.tables{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:14px;
  margin-bottom:18px}
.tbl{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:14px}
.tbl.ready{border-color:var(--rose);border-style:dashed}
.tbl.over{border-color:var(--stop)}
.thead{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:9px}
.thead b{font-family:var(--display);font-size:18px;font-weight:600}
.tcount{font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums}
.tcount.bad{color:var(--stop);font-weight:700}
.tfoot{margin-top:11px;min-height:30px;display:flex;align-items:center}
.btn.small{padding:6px 12px;font-size:13px}
.none.small{font-size:12.5px;padding:0}

.tfix{display:flex;gap:6px;align-items:center;margin-top:11px}
.tfix[hidden]{display:none}
.tfix .tname{flex:1;min-width:0;padding:7px 9px;font-size:13.5px}
.tfix .tseats{width:66px;flex:0 0 66px;padding:7px 9px;font-size:13.5px}
.tfoot[hidden]{display:none}

/* ---------- day-of timeline ----------
   A running order is a table, and the honest thing is to draw it as one: four
   columns, a heading over each, and every cell the box itself rather than a
   line of text hiding a box behind a pencil.

   Laid out with grid rather than a real <table> because the same four columns
   have to fold into a stack on a phone, which a table cannot do. */
.tlcard{padding:0;overflow:hidden}
.tlcard .msg{margin:14px 16px 0}
/* .note caps its width for readability, which would have stopped this one's
   rule short of the right-hand edge — a line across two thirds of a card. */
.tlcard > .note{margin:0;padding:11px 16px 14px;border-top:1px solid var(--line);
  max-width:none}

.tl{list-style:none;margin:0;padding:0}
.tl .tlrow, .tl .tlhead{display:grid;align-items:center;gap:10px;
  grid-template-columns:minmax(120px,max-content) minmax(150px,1.5fr)
                        minmax(110px,0.9fr) minmax(150px,1.5fr) 30px;
  padding:9px 16px}
.tl .tlhead{padding:12px 16px;background:var(--surface-2);
  border-bottom:1px solid var(--line);
  font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-3)}
.tl .tlrow + .tlrow{border-top:1px solid var(--line)}

/* The time. Shown the couple's way — 2:00 pm or 14:00, their choice — and it
   becomes a real time box only while it is being changed, so the browser's
   own idea of how a clock should read never overrides theirs. Lining figures
   so the column runs straight down the page, which is what a running order is
   read for. */
.tltimebtn{display:flex;align-items:center;gap:7px;padding:8px 10px;
  background:none;border:1px solid transparent;border-radius:9px;
  font:inherit;color:var(--ink-3);cursor:pointer;text-align:left}
.tltimebtn:hover{border-color:var(--line-2);background:var(--surface-2)}
.tltimebtn:focus-visible{outline:2px solid var(--rose);outline-offset:1px}
.tltimebtn svg{width:15px;height:15px;flex:0 0 15px}
.tltime{font-variant-numeric:tabular-nums;font-weight:700;font-size:14px;
  color:var(--rose);white-space:nowrap}
.tltimebox{font:inherit;font-size:14px;font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--ink);
  background:var(--surface);border:1px solid var(--rose);border-radius:9px;
  padding:7px 9px;width:100%}

/* Every other cell, drawn as a box and left that way.

   The first version made the border appear on hover, so the cells read as
   plain text until the mouse went near them. That is the wrong way round for
   this screen: the whole reason for rebuilding it was that a couple could not
   see where to click. A box says "type here" without anybody having to
   discover it, and on a phone there is no hover to discover it with. */
.tlcell{width:100%;min-width:0;font:inherit;font-size:14.5px;color:var(--ink);
  background:var(--surface);border:1px solid var(--line-2);border-radius:9px;
  padding:8px 10px}
.tlcell::placeholder{color:var(--ink-3)}
.tlcell:hover{border-color:var(--ink-3)}
.tlcell:focus{outline:none;border-color:var(--rose);box-shadow:0 0 0 2px var(--rose-soft)}
.tlcell.saving{opacity:.6}

/* ---------- the running order on a phone ----------
   Four columns will not fit and squeezing them makes every one of them
   useless. So each line becomes its own small block with its heading beside
   it, and the headings above disappear. */
@media(max-width:760px){
  .tl .tlhead{display:none}
  .tl .tlrow{grid-template-columns:1fr 30px;
    grid-template-areas:"time del" "title title" "who who" "notes notes";
    gap:6px;padding:12px 14px}
  .tl .tlrow .tltimebtn, .tl .tlrow .tltimebox{grid-area:time;justify-self:start}
  .tl .tlrow .tact{grid-area:del}
  .tl .tlcell[data-tlfield=title]{grid-area:title;font-size:15.5px}
  .tl .tlcell[data-tlfield=who]{grid-area:who}
  .tl .tlcell[data-tlfield=detail]{grid-area:notes}
  /* With no heading above them, the two smaller boxes need to say what they
     are for even once they have something in them. */
  .tl .tlcell[data-tlfield=who], .tl .tlcell[data-tlfield=detail]{
    font-size:13.5px;color:var(--ink-2);border-color:var(--line)}
}

/* ---------- suppliers ---------- */
.stat{flex:0 0 auto;font-size:10.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;padding:3px 9px;border-radius:99px;
  background:var(--surface-2);color:var(--ink-3);white-space:nowrap}
.stat.contacted{color:var(--ink-2)}
.stat.quoted{background:rgba(176,138,56,.14);color:var(--gold)}
.stat.booked{background:var(--good-soft);color:var(--good)}
.stat.passed{opacity:.6;text-decoration:line-through}

@media(max-width:560px){
  .tltime{flex:0 0 56px;font-size:13px}
  .tl .tlrow{gap:10px;padding:10px 11px}
}

/* ---------- the wedding website, couple's side ---------- */
textarea{width:100%;font:inherit;font-size:15px;color:var(--ink);background:var(--surface);
  border:1px solid var(--line-2);border-radius:9px;padding:10px 12px;resize:vertical;
  line-height:1.55}
textarea:focus{outline:2px solid var(--rose);outline-offset:1px;border-color:var(--rose)}

.slugrow{display:flex;align-items:center;gap:0;border:1px solid var(--line-2);
  border-radius:9px;background:var(--surface);overflow:hidden}
.slugrow span{padding:10px 0 10px 12px;font-size:13.5px;color:var(--ink-3);white-space:nowrap}
.slugrow input{border:0;border-radius:0;padding-left:2px;background:none}
.slugrow input:focus{outline:2px solid var(--rose);outline-offset:-2px}

.pubrow{display:flex;align-items:center;gap:16px;justify-content:space-between;
  flex-wrap:wrap;margin-bottom:16px}
.urlrow{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.urlrow input{flex:1;min-width:180px;font-size:13.5px;color:var(--ink-2)}
.urlrow .ghost{text-decoration:none;display:inline-flex;align-items:center}

/* Two buttons of equal weight, filling the width the repeated address used. */
.linkrow{display:flex;gap:8px;margin-top:14px}
.linkrow .ghost{flex:1;text-align:center;text-decoration:none;
  display:inline-flex;align-items:center;justify-content:center;padding:10px 12px}

.check{display:flex;align-items:flex-start;gap:10px;padding:9px 0;font-size:14.5px}
.check input{width:18px;height:18px;flex:0 0 18px;margin-top:2px;accent-color:var(--rose)}

/* ============================================================
   The guest's page — a different room from the app
   ============================================================ */
.guestpage{background:var(--paper)}
.gwrap{width:100%;max-width:660px;margin:0 auto;padding:26px 20px 50px}
.loading{text-align:center;color:var(--ink-3);padding:60px 20px}

/* ---------- the band across the top ----------
   Their wording, their names, the day and the place. Full width, its own
   colour, and on every page — a guest who arrives on Accommodation from a
   WhatsApp link can see whose wedding this is without tapping anything. */
/* The same paper as the rest of the page — same colour, same grain, no
   gradient laid over it. It used to be mixed from the CARD colour, which on
   every dark theme is lighter than the page, so the top of the wedding site
   looked like it had a pale sheet over it and the join showed at the nav. */
.ghd{background-color:var(--sbg,var(--paper));
  background-image:var(--stexi,none);background-size:var(--stexs,auto);
  padding:34px 30px 26px;text-align:center;position:relative;overflow:hidden}
.ghdin{position:relative;z-index:1;max-width:760px;margin:0 auto}
.gamp{font-family:var(--sdisp,var(--display));font-size:clamp(27px,6.4vw,40px);
  font-weight:600;line-height:1.12;color:var(--sink,var(--ink));letter-spacing:.05em}
.gdt{margin-top:8px;font-size:clamp(9.5px,2.4vw,11.5px);letter-spacing:.2em;
  text-transform:uppercase;color:var(--sink2,var(--ink-2))}

/* the eight ways the wording above the names can look */
.eyeC{font-family:var(--sbody,inherit);font-size:12px;letter-spacing:.34em;
  text-transform:uppercase;color:var(--sgold,var(--gold));font-weight:600;margin-bottom:14px}
.eyeS{font-family:'Pinyon Script',cursive;font-size:clamp(30px,8vw,40px);
  line-height:1.05;color:var(--sgold,var(--gold));margin-bottom:8px}
.eyeM{margin-bottom:10px;display:flex;align-items:baseline;justify-content:center;
  gap:10px;flex-wrap:wrap}
.eyeM .c{font-family:var(--sbody,inherit);font-size:15px;letter-spacing:.26em;
  text-transform:uppercase;color:var(--sgold,var(--gold));font-weight:500}
.eyeM .s{font-family:'Pinyon Script',cursive;font-size:clamp(30px,8vw,40px);
  line-height:1;color:var(--sgold,var(--gold))}

/* capitals with a hairline either side */
.eyeR{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:14px}
.eyeR span{font-family:var(--sbody,inherit);font-size:11.5px;letter-spacing:.3em;
  text-transform:uppercase;color:var(--sgold,var(--gold));font-weight:600;white-space:nowrap}
.eyeR i{display:block;width:clamp(22px,9vw,64px);height:1px;
  background:var(--sgold,var(--gold));opacity:.75;flex:none}

/* capitals set very wide — for two or three short words */
.eyeW{font-family:var(--sbody,inherit);font-size:clamp(11px,2.6vw,14px);
  letter-spacing:.52em;text-indent:.52em;text-transform:uppercase;
  color:var(--sgold,var(--gold));font-weight:500;margin-bottom:16px}

/* a script line with a short rule beneath it */
.eyeSR{margin-bottom:12px}
.eyeSR span{display:block;font-family:'Pinyon Script',cursive;
  font-size:clamp(30px,8vw,40px);line-height:1.05;color:var(--sgold,var(--gold))}
.eyeSR i{display:block;width:52px;height:1px;margin:6px auto 0;
  background:var(--sgold,var(--gold));opacity:.75}

/* a script line over a line of capitals */
.eyeK{margin-bottom:12px}
.eyeK .s{display:block;font-family:'Pinyon Script',cursive;
  font-size:clamp(28px,7vw,38px);line-height:1.05;color:var(--sgold,var(--gold))}
.eyeK .c{display:block;font-family:var(--sbody,inherit);font-size:10.5px;
  letter-spacing:.28em;text-transform:uppercase;color:var(--sgold,var(--gold));
  font-weight:600;margin-top:5px}

/* their own initials, with a rule between */
.eyeI{display:flex;align-items:center;justify-content:center;gap:13px;margin-bottom:12px}
.eyeI span{font-family:var(--sdisp,var(--display));font-size:clamp(26px,6vw,34px);
  line-height:1;color:var(--sgold,var(--gold));letter-spacing:.04em}
.eyeI i{display:block;width:1px;height:clamp(24px,5.5vw,32px);
  background:var(--sgold,var(--gold));opacity:.8;flex:none}

/* ---------- the tabs, as their own band under the names ---------- */
/* One row, always. Nine pages wrapped onto three lines on a phone, which ate
   a third of the screen before a guest had read a word — and a menu that grows
   downward pushes the wedding off the top of its own page.
   justify-content is safe-centre: centred while they all fit, but never
   pushing the first one off the left edge once they do not. */
.gtabs{display:flex;justify-content:safe center;gap:2px;flex-wrap:nowrap;
  padding:9px 14px;overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;-ms-overflow-style:none;
  background:var(--scard,var(--surface));
  border-bottom:1px solid var(--sline,var(--line));position:sticky;top:0;z-index:2}
.gtabs::-webkit-scrollbar{display:none}
.gtabs button{background:none;border:0;font-size:10.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--sink2,var(--ink-2));padding:6px 9px;
  border-radius:6px;font-weight:700;cursor:pointer;
  flex:0 0 auto;white-space:nowrap;scroll-snap-align:center}
.gtabs button:hover{color:var(--sacc,var(--rose))}
.gtabs button.on{background:var(--sink,var(--ink));color:var(--sbg,var(--paper))}

/* ---------- the front page ---------- */
.ghome{text-align:center}
.grule{width:44px;height:1px;background:var(--sgold,var(--gold));margin:26px auto 18px}
.kv{background:var(--scard,var(--surface));border:1px solid var(--sline,var(--line));
  border-radius:14px;padding:18px 20px;margin-top:12px;text-align:center}
.kv h4{font-family:var(--sbody,inherit);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--sgold,var(--gold));font-weight:700;margin:0 0 8px}
.kv .big{font-family:var(--sdisp,var(--display));font-size:22px;font-weight:600;line-height:1.25}
.kv .sm{font-size:13.5px;color:var(--sink2,var(--ink-2));margin-top:5px}
.gtogo{display:inline-block;margin-top:12px;font-size:11px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--sacc,var(--rose));
  border:1px solid var(--sline,var(--line));border-radius:99px;padding:5px 14px}
/* Equal air above and below. It had none underneath, so it sat against the
   card below it and read as part of that card rather than as the end of this
   one. */
.gcta{background:var(--sink,var(--ink));color:var(--sbg,var(--paper));border:0;
  border-radius:99px;padding:14px 30px;font-size:13px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;display:block;margin:24px auto;cursor:pointer}
.ghome{margin-bottom:4px}
.gcta:hover{filter:brightness(1.08)}

/* ---------- the band across the bottom ---------- */
.gft{text-align:center;padding:22px 20px 26px;
  border-top:1px solid var(--sline,var(--line));background:var(--scard,var(--surface))}
.gini{font-family:var(--sdisp,var(--display));font-size:20px;font-weight:600;
  color:var(--sacc,var(--rose));letter-spacing:.12em}
.gfd{font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sink3,var(--ink-3));margin-top:4px}
.gcr{font-size:10px;color:var(--sink3,var(--ink-3));opacity:.75;margin-top:12px;
  letter-spacing:.04em}

.gstory p{margin:0 0 12px;line-height:1.75}
.gstory p:last-child{margin-bottom:0}

/* ---------- gifts ---------- */
.gifts{list-style:none;margin:0 0 18px;padding:0;display:grid;gap:12px}
/* Every row the same height as the tallest — but ONLY in the row shape, where
   the square picture is the same size on every card anyway so the evening-up
   costs nothing. In the stacked shape it was ruinous: one gift with a picture
   made every gift WITHOUT one grow to match, so a plain name sat alone in the
   middle of an empty card the size of a photo. */
.gifts.beside{grid-auto-rows:1fr}
.gift{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:16px}
/* A picture of the thing, above its name. Guests choose what they can see. */
.gpic{display:block;width:100%;aspect-ratio:1;border-radius:10px;margin:0 0 12px;
  background-color:var(--sline,var(--line));background-size:cover;background-position:50% 50%}

/* In the stacked shape a card with no picture is simply a shorter card. */
.gift:not(.beside):not(.haspic){padding:18px 16px}

/* ---------- the other shape: the picture beside the name ----------
   The row is a flex box with the picture stretched to it, so the picture is
   exactly as tall as the words next to it — which is to say exactly as tall
   as a gift with no picture at all. No fixed height anywhere: the words decide
   how tall the row is, and the picture follows. */
.gift.beside{display:flex;gap:14px;align-items:stretch}
/* A square, always — the picture is of a thing, and a thing squashed into a
   letterbox stops looking like itself. */
.gift.beside .gpic{flex:0 0 104px;width:104px;height:104px;aspect-ratio:1;
  margin:0;align-self:center}
/* The words sit AGAINST the picture rather than floating in the middle of the
   space left over, so the eye goes picture → name without a gap in between.
   The price and the button keep their own column on the right. */
.gift.beside .gbody{flex:1;min-width:0;display:flex;gap:14px;align-items:stretch}
.gift.beside .gsay{flex:1;min-width:0;text-align:left;
  display:flex;flex-direction:column;justify-content:center}
.gift.beside .gact{flex:0 0 auto;display:flex;flex-direction:column;
  align-items:flex-end;justify-content:space-between;gap:10px;text-align:right}
.gift.beside .gact .btn.small{margin:0}
/* .gname is also the guest-list row's name, which is flex:1 so it can push
   the buttons to the end of that row. Inherited here it stretched the title
   down the card and shoved the note to the bottom. */
.gift .gname{flex:0 0 auto;display:block;min-width:0}
@media (max-width:520px){
  /* Evening the rows up is right in the ROW shape, where every picture is the
     same 104px square and matching heights costs nothing. Down here that shape
     has become a stacked one and the picture has become a full-width square —
     so a gift with a photograph is three hundred pixels taller than a gift
     without, and the rule dragged every plain gift up to match. A blanket, a
     shop and a price sat at the top of a card the size of a photograph with
     nothing underneath them. Each card is its own height again. */
  .gifts.beside{grid-auto-rows:auto}
  /* No room for three columns once the name has anywhere to go. */
  .gift.beside{display:block}
  .gift.beside .gpic{width:100%;height:auto;aspect-ratio:1;margin:0 0 12px}
  .gift.beside .gbody{display:block}
  .gift.beside .gact{align-items:center;text-align:center;margin-top:10px}
}

/* the sentence at the top of Accommodation and Things to do, in the couple's
   own words or in ours */
/* text-align does not inherit past a rule that sets it, and the centring rule
   below only reaches paragraphs that are DIRECT children of the card. These
   sit one level deeper, inside this wrapper, which is exactly how the couple's
   own wording came out centred while BrideHub's fallback did not. */
.pintro{margin:0 0 18px;text-align:center}
.pintro p{margin:0 0 8px;text-align:center}
.pintro p:last-child{margin-bottom:0}
.gift.claimed{border-color:var(--rose);background:var(--rose-soft)}
/* The stacked shape: name and price on one line, everything centred. */
.gift:not(.beside) .gbody{display:flex;flex-direction:column;gap:6px;text-align:center}
.gift:not(.beside) .gact{display:flex;flex-direction:column;align-items:center;gap:8px}
.gtop{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.gift .gname{font-family:var(--display);font-size:19px;font-weight:600}
.gprice{font-size:13px;color:var(--ink-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.gnote{font-size:13.5px;color:var(--ink-2);margin:6px 0 0}
.gnote a{color:var(--rose)}
.gift .btn.small{margin-top:12px}
.gmine{font-size:13.5px;color:var(--rose);margin:12px 0 0;font-weight:600}

/* ---------- photos ---------- */
.photorow{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:18px}
.photorow .ghost{margin-right:6px}
.ringbig{width:96px;height:96px;flex:0 0 96px;border-radius:50%;
  background:var(--surface-2);border:2px solid var(--rose);
  background-size:cover;background-position:50% 50%;display:block}
.whoami .wpic.has{color:transparent}
.herothumb{width:120px;height:68px;flex:0 0 120px;border-radius:10px;
  background:var(--surface-2);border:1px solid var(--line-2);
  background-size:cover;background-position:50% 50%;display:block}

.croppy{display:flex;gap:18px;align-items:flex-start;flex-wrap:wrap;margin:18px 0}
.cpstage{position:relative;width:230px;height:230px;flex:0 0 230px;border-radius:12px;
  background-color:var(--surface-2);background-size:cover;cursor:grab;
  touch-action:none;overflow:hidden;user-select:none}
.cpstage:active{cursor:grabbing}
/* closest-side, not the default farthest-corner — otherwise the clear circle
   is larger than the ring drawn on top of it and the crop lies to you. */
.cpmask{position:absolute;inset:0;
  -webkit-mask:radial-gradient(circle closest-side at 50% 50%,transparent 0 99%,#000 100%);
  mask:radial-gradient(circle closest-side at 50% 50%,transparent 0 99%,#000 100%);
  background:var(--surface);opacity:.82;
  box-shadow:inset 0 0 0 1px var(--line)}
/* A square window, for a thing rather than a face. There is nothing to grey
   out here: the whole stage IS the crop, so the mask goes and a plain edge
   stays to show where it ends. */
.cpstage.sq .cpmask{-webkit-mask:none;mask:none;background:none;opacity:1}
.cptools{flex:1;min-width:200px}
.cptools input[type=range]{width:100%;accent-color:var(--rose)}

/* ---------- theme swatches ---------- */
.swatches{display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr));gap:10px}
.swatch{position:relative;border:1.5px solid;border-radius:12px;padding:12px 12px 10px;
  cursor:pointer;text-align:left;display:flex;gap:5px;align-items:center;flex-wrap:wrap}
.swatch span{width:16px;height:16px;border-radius:50%;display:block}
.swatch em{flex:1 0 100%;font-style:normal;font-size:13px;margin-top:8px}
.swatch.on{outline:2px solid var(--rose);outline-offset:2px}

/* ---------- the preview ---------- */
.prevtag{margin:0;padding:8px 14px;font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;font-weight:700;color:var(--ink-3);
  background:var(--surface-2);border-bottom:1px solid var(--line)}
.preview{background:var(--sbg);padding:0 0 26px;text-align:center}
.pvhero{height:130px;background-size:cover;background-position:50% 40%}
.pvbody{padding:24px 18px 0}
.pveye{margin:0 0 9px;font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  font-weight:700;color:var(--sgold)}
.pvnames{font-family:var(--sdisp);font-size:30px;font-weight:600;line-height:1.1;
  margin:0 0 10px;color:var(--sink)}
.pvdate{font-family:var(--sdisp);font-size:15px;margin:0;color:var(--sink2)}
.pvwhere{font-size:13px;margin:3px 0 0;color:var(--sink3)}
.pvcount{display:inline-block;margin:16px 0 0;font-size:10.5px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--sacc);
  border:1px solid var(--sline);border-radius:99px;padding:5px 14px}

/* ============================================================
   The guest page wears the couple's theme, not the visitor's
   ============================================================ */
.guestpage{background-color:var(--sbg,var(--paper));color:var(--sink,var(--ink));
  font-family:var(--sbody,inherit);
  background-image:var(--stexi,none);background-size:var(--stexs,auto)}
/* The couple's body face reaches the things a guest actually reads at length —
   but not the headings, which have a face of their own. */
.guestpage p,.guestpage li,.guestpage input,.guestpage select,.guestpage textarea,
.guestpage button,.guestpage dt,.guestpage dd,.guestpage .gtabs button{
  font-family:var(--sbody,inherit)}
.guestpage h3{font-family:var(--sdisp,var(--display))}
/* A heading and the words under it sit ON the couple's paper, not on a white
   panel laid over it. The texture and the colour are the whole point of
   choosing a theme, and a card in the middle of the page hides both — the
   page ends up looking like a form rather than like an invitation.

   Only SECTIONS lose the panel. A form still gets one, because boxes a guest
   types into need a surface to sit on to read as boxes at all. */
.guestpage section.card{background:none;border:0;box-shadow:none;padding:26px 0 6px}
.guestpage form.card,.guestpage div.card{
  background:var(--scard,var(--surface));border-color:var(--sline,var(--line))}

/* The short gold rule above a heading. Drawn by the heading itself rather than
   added to six different places in the page, so it cannot be forgotten on the
   seventh. */
.guestpage section.card > h2::before{content:"";display:block;
  width:44px;height:1px;background:var(--sgold,var(--gold));margin:0 auto 18px}

/* A short page should still put its footer at the bottom, not halfway down
   with a field of empty paper underneath. */
.guestpage #site{flex:1;display:flex;flex-direction:column}
.guestpage .gft{margin-top:auto}
.guestpage h1,.guestpage h2,.guestpage .gname{font-family:var(--sdisp,var(--display));
  color:var(--sink,var(--ink))}
.guestpage .stand{color:var(--sink2,var(--ink-2))}
.guestpage .note,.guestpage .gprice,.guestpage .none,
.guestpage .facts dt,.guestpage .foot{color:var(--sink3,var(--ink-3))}
.guestpage .facts{background:var(--sline,var(--line))}
.guestpage .facts div{background:var(--scard,var(--surface))}
.guestpage .ghead{font-family:var(--sdisp,var(--display));font-size:19px;
  color:var(--sink2,var(--ink-2));margin:0 0 4px;text-align:center}
.guestpage .btn{background:var(--sacc,var(--rose))}
/* A gift card was wearing the APP's white surface while its writing took the
   COUPLE's ink. On a pale theme that happens to work; on any of the ten dark
   ones it is cream lettering on white, which is to say nothing at all. The
   card belongs to the couple's page, so it takes the couple's colours. */
.guestpage .gift{background:var(--scard,var(--surface));
  border-color:var(--sline,var(--line))}
.guestpage .gift .btn.small{background:var(--sink,var(--ink));color:var(--sbg,#fff)}
.guestpage .gift.claimed{border-color:var(--sacc,var(--rose));background:transparent}
.guestpage .gmine,.guestpage .gnote a,.guestpage .linky:hover{color:var(--sacc,var(--rose))}
.guestpage .foot{border-top-color:var(--sline,var(--line))}

/* A wide photo above the names, cropped by the browser rather than by
   the couple — a banner forgives a loose crop in a way a circle does not. */
/* Exactly sixteen by nine, at every width, with nothing that can squash it.
   The white box in the editor is drawn to this shape and the crop is worked
   out from it, so the moment the band on the page is any OTHER shape — a
   max-height clamping it on a wide screen, say — the couple is shown one thing
   and their guests another. That is not a near miss: at 1400px a height cap
   moved the framing by half the height of the photo. */
.ghero-img{width:100%;aspect-ratio:16/9;background-size:cover;
  background-position:50% 42%;background-color:var(--sh1,var(--surface-2));display:block}

/* ---------- replies ---------- */
.reply{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;
  border-top:1px solid var(--line)}
.reply:first-child{border-top:0}
.reply .gname{flex:1}
.rmsg{display:block;font-size:13px;color:var(--ink-2);margin-top:5px;font-style:italic}
.rbtns{flex:0 0 auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.reply.no .gname{color:var(--ink-2)}
.rsvpset{border-left:2px solid var(--line);padding-left:14px;margin:12px 0 0}
.rsvpset[hidden]{display:none}

/* ---------- a household answering ---------- */
.pers{border-top:1px solid var(--sline,var(--line-2));padding:16px 0 4px}
.pers:first-child{border-top:0;padding-top:0}
.pname{font-family:var(--serif,Georgia,serif);font-size:19px;font-weight:600;
  margin:0 0 10px;color:var(--sink,var(--ink))}
.dietfld{margin-top:10px}
.dietfld[hidden]{display:none}
.saidlist{list-style:none;padding:0;margin:14px 0 4px;font-size:15.5px;
  color:var(--sink,var(--ink));line-height:1.9}
.rans{display:block;font-size:13px;color:var(--ink-2);margin-top:5px}
.misses{margin:18px 2px 0;line-height:1.75}
.misses b{color:var(--ink)}

/* ---------- the guest's yes / no ---------- */
.pickrow{display:flex;gap:8px;flex-wrap:wrap}
.pick{flex:1;min-width:140px;border:1.5px solid var(--sline,var(--line-2));
  background:var(--scard,var(--surface));color:var(--sink2,var(--ink-2));
  font:inherit;font-size:14.5px;padding:12px 14px;border-radius:10px;cursor:pointer}
.pick.on{border-color:var(--sacc,var(--rose));color:var(--sacc,var(--rose));font-weight:700}
.guestpage textarea{background:var(--scard,var(--surface));color:var(--sink,var(--ink));
  border-color:var(--sline,var(--line-2))}
.guestpage input{background:var(--scard,var(--surface));color:var(--sink,var(--ink));
  border-color:var(--sline,var(--line-2))}

/* ---------- the three typed pages, in the app ---------- */
.back{display:inline-block;margin:0 0 10px;font-size:14px}
.ord{flex:0 0 auto;display:flex;flex-direction:column;gap:2px;margin-right:2px}
/* Big enough for a thumb. 20px squares were not. */
.ord .x{width:30px;height:28px;line-height:1;font-size:12px;padding:0}
.ord .x[disabled]{opacity:.25;cursor:default}
.pface{flex:0 0 auto;width:38px;height:38px;border-radius:50%;
  background:var(--line);background-size:cover;background-position:50% 50%;
  display:flex;align-items:center;justify-content:center;
  font-size:13px;font-weight:700;color:var(--ink-2);letter-spacing:.5px}
.pface.big{width:72px;height:72px;font-size:22px}
.phrow{display:flex;align-items:center;gap:12px;flex-wrap:wrap}

/* a picture of a registry item — a square, not a circle: a cast-iron pot is
   not a face */
.rpic{flex:0 0 auto;width:46px;height:46px;border-radius:9px;
  background:var(--surface-2);background-size:cover;background-position:50% 50%}
.rpic.big{width:72px;height:72px;border-radius:11px}







/* ---------- and on the guest's page ---------- */
.gqa h3{font-family:var(--serif,Georgia,serif);font-size:19px;margin:0 0 6px;
  color:var(--sink,var(--ink))}
.qa,.stay{padding:18px 0;border-top:1px solid var(--sline,var(--line-2))}
.qa:first-of-type,.stay:first-of-type{border-top:0;padding-top:4px}
.qa p,.stay p{margin:0 0 8px;line-height:1.75}
.stmeta{font-size:13.5px;color:var(--sink2,var(--ink-2));margin:0 0 8px!important}
.stlinks{display:flex;gap:16px;flex-wrap:wrap;margin:10px 0 0!important}
.stlinks a{color:var(--sacc,var(--rose));font-size:14.5px}

/* The whole guest page is a centred, symmetrical thing — the names, the day,
   the reception, the page buttons. The written pages were the one part still
   ranged left, which read as though they belonged to a different site. */
.guestpage .card h2,
.guestpage .gqa h3,
.guestpage .qa,
.guestpage .stay,
.guestpage .gstory p,
.guestpage .card > p{text-align:center}
.guestpage .stlinks{justify-content:center}
/* Both of these cap their width so a line of text stays readable — but a
   capped block with no side margins sits at the LEFT of whatever holds it.
   The words inside were centred; the block they were centred in was not, so
   the whole paragraph sat off to one side of a page that is centred. */
.guestpage .stand,.guestpage .note,.guestpage .none{margin-left:auto;margin-right:auto}
/* A gift is a row, not a paragraph — it has its own arrangement, set with the
   layout rules above rather than by the page's general centring. */

.pgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:28px 20px;margin-top:22px}
.pcard{text-align:center}
/* Twice what it was. These are the people standing up with them; a face the
   size of a thumbnail is not a photo of anybody. */
.pcard .pface{margin:0 auto 14px;width:144px;height:144px;font-size:40px}
@media (max-width:430px){.pcard .pface{width:124px;height:124px;font-size:34px}}
/* Somebody with no photo gets their name and nothing else, so a mixed
   page does not read as a row of missing pictures. A little air on top keeps
   them level with the names beside them. */
.pcard.nopic{padding-top:10px}
.pcard h3{font-family:var(--serif,Georgia,serif);font-size:18px;margin:0 0 2px;
  color:var(--sink,var(--ink))}
.prole{font-size:13px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--sacc,var(--rose));margin:0 0 8px!important}
.pcard p{font-size:14.5px;line-height:1.7;margin:0;color:var(--sink2,var(--ink-2))}

.needs{color:var(--gold,#9a7b2f);font-style:italic}

/* ---------- the pages list ---------- */



/* ---------- the photo grid, in the app ---------- */
.pgrid-ed{list-style:none;padding:0;margin:0 0 18px;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
.pcell{position:relative;border-radius:10px;overflow:hidden;background:var(--line)}
.pimg{display:block;aspect-ratio:1;background-size:cover;background-position:50% 50%}
.pcellbtns{position:absolute;left:0;right:0;bottom:0;display:flex;gap:4px;
  padding:6px;background:linear-gradient(transparent,rgba(0,0,0,.55))}
.pcellbtns .x{width:30px;height:28px;padding:0;font-size:12px;
  background:rgba(255,255,255,.92);border-color:transparent;color:#222}
.pcellbtns .x[disabled]{opacity:.35}
.pcellbtns .x:last-child{margin-left:auto}

/* ---------- and on the guest's page ---------- */
.pg{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:10px;margin-top:20px}
.pgimg{display:block;width:100%;aspect-ratio:1;border-radius:10px;border:0;padding:0;
  cursor:pointer;background-size:cover;background-position:50% 50%;
  background-color:var(--sline,var(--line))}
.pgimg:focus-visible{outline:2px solid var(--sacc,var(--rose));outline-offset:2px}
/* Each page is a card a guest can see the edge of. They were hairlines on the
   background before, which read as a list rather than as things to press. */
.feed{display:flex;flex-direction:column;gap:8px;margin:0}
.feed button{display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;background:var(--scard,var(--surface));
  border:1px solid var(--sline,var(--line-2));border-radius:12px;
  font-family:var(--sdisp,var(--display));font-size:20px;font-weight:600;
  color:var(--sink,var(--ink));padding:15px 18px;cursor:pointer;text-align:left}
.feed button:hover{border-color:var(--sacc,var(--rose))}
.feed button i{font-style:normal;color:var(--sgold,var(--gold));
  font-family:var(--sbody,inherit);font-size:17px}

/* ---------- the website editor: work on the left, the real page on the right ---------- */
.tabrow{display:flex;align-items:center;flex-wrap:wrap;gap:10px;margin:0 0 18px}
.tabs{display:flex;gap:4px;background:var(--surface-2);padding:4px;border-radius:10px}
/* The general .tabs further up carries margin-bottom:20px, for the places
   where a set of tabs stands alone above its panel. In this row it is dead
   space that made the row twenty pixels taller than it looked — and because
   the row centres its children, that pushed the little screen/phone switch
   ten pixels down, so its bottom edge sat below the tabs beside it. */
.tabrow .tabs{margin:0}
.tabs button{background:none;border:0;border-radius:7px;padding:8px 18px;font:inherit;
  font-size:14px;font-weight:600;color:var(--ink-2);cursor:pointer}
.tabs button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.08)}
/* Stretched rather than given a height of its own: whatever the tabs beside it
   come to, the switch matches, so the two never drift apart again. */
.vwtog{display:flex;gap:4px;background:var(--surface-2);padding:4px;border-radius:10px;
  align-self:stretch}
.vwtog button{background:none;border:0;border-radius:7px;padding:0 12px;
  color:var(--ink-2);cursor:pointer;line-height:0;display:flex;align-items:center;
  justify-content:center;min-width:40px}
.vwtog button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.08)}
.savetag{font-size:13px;color:var(--green,#2f6f4f);margin-left:auto}
.savetag.bad{color:var(--red,#a33)}
.savetag[hidden]{display:none}

.split{display:grid;grid-template-columns:minmax(300px,390px) minmax(0,1fr);
  gap:22px;align-items:start}
/* The heading and the tabs live in this half, which is why the preview beside
   it can start at the very top of the screen. */
/* The website screen is exactly one windowful: the bar, then this, and no
   page scroll at all. That is what lets the preview run to the bottom of the
   screen — with nothing below it to scroll to, nothing can slide up under the
   bar, and each column scrolls inside itself instead. */
.split{height:calc(100vh - 100px);min-height:500px}
.edside{display:flex;flex-direction:column;min-width:0;height:100%;min-height:0}
.edside h1{margin-top:0}
/* Each half scrolls on its own, so the preview stays put while they work. */
.edcol{display:flex;flex-direction:column;gap:16px;flex:1;min-height:0;
  overflow-y:auto;padding-right:6px}
.pvcol{height:100%;min-height:0;display:flex;flex-direction:column}
.edcol::-webkit-scrollbar,.pvcol::-webkit-scrollbar{width:9px}
.edcol::-webkit-scrollbar-thumb,.pvcol::-webkit-scrollbar-thumb{
  background:var(--line-2);border-radius:99px}

.frame{border:1px solid var(--line);border-radius:14px;overflow:hidden;
  background:var(--surface);box-shadow:0 2px 10px rgba(0,0,0,.06);
  transition:max-width .18s ease;
  flex:1;min-height:0;display:flex;flex-direction:column;width:100%}
.frame.mob{max-width:390px;margin:0 auto}
.frame .urlbar{background:var(--surface-2);border-bottom:1px solid var(--line);
  padding:9px 14px;font-size:12px;color:var(--ink-2);display:flex;gap:7px;align-items:center}
.frame .urlbar i{width:9px;height:9px;border-radius:99px;background:var(--line-2);flex:none}
.frame .urlbar code{font-family:inherit;color:var(--ink);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
/* The bar stays on screen, so the preview has to fit BELOW it. 60 for the bar,
   24 of air, 38 for the little address strip, 34 for the line underneath, and
   a few to spare — anything taller and the top of the preview slides under the
   bar when the page is scrolled to the bottom. */
.frame iframe{display:block;width:100%;flex:1;min-height:0;height:auto;border:0}
/* .note caps its width for readability, which left this one centred inside a
   narrow box rather than under the preview. Here the whole width is the point. */
.pvnote{text-align:center;margin:10px auto 0;max-width:none;width:100%}

.tinyhead{font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);font-weight:700;margin:0 0 10px;font-family:inherit}
.pgpick{display:flex;flex-wrap:wrap;gap:6px}
.pgp{background:var(--surface-2);border:1px solid transparent;border-radius:99px;
  padding:7px 14px;font:inherit;font-size:13.5px;color:var(--ink-2);cursor:pointer}
.pgp.on{background:var(--rose);border-color:var(--rose);color:#fff;font-weight:600}
.pgp.off{opacity:.55}
.pgp i{font-style:normal;font-size:10px;letter-spacing:.06em;text-transform:uppercase;opacity:.8}
.addbox{border-top:1px solid var(--line);margin-top:18px;padding-top:16px}
.blist.tight .bitem{padding-left:0;padding-right:0}

@media (max-width:900px){
  .split{grid-template-columns:1fr}
  .split{height:auto;min-height:0}
  .edside,.edcol,.pvcol{height:auto;max-height:none;overflow:visible;position:static}
  .frame{display:block}
  .frame iframe{height:70vh;min-height:420px;flex:none}
  .frame iframe{height:70vh}
}

/* Inside the editor's frame the page is a panel, not a whole browser window:
   no page margin of its own, and it scrolls within the frame. */
body.inpreview{margin:0}
body.inpreview .gwrap{padding-top:18px}
body.inpreview .foot{margin-top:24px}

/* ---------- what one guest answered ---------- */
.gans{display:block;font-size:13px;color:var(--ink-2);margin-top:4px}
.gans b{color:var(--ink);font-weight:600}
.saidbit{font-size:13px;color:var(--sink2,var(--ink-2))}
.dietwrap{margin-top:8px}
.dietwrap[hidden]{display:none}
.pers .fld.ifyes[hidden]{display:none}
.guestpage select{background:var(--scard,var(--surface));color:var(--sink,var(--ink));
  border-color:var(--sline,var(--line-2))}

/* ---------- choosing lettering ---------- */
.fontpick{font-size:16px}
.fontpick option{font-size:16px;padding:4px}

/* ---------- choosing a texture ---------- */
.texgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(108px,1fr));gap:8px}
.texsw{border:1.5px solid var(--line);border-radius:10px;padding:0;overflow:hidden;
  background:var(--surface);cursor:pointer;text-align:left;font:inherit}
.texsw.on{border-color:var(--rose);box-shadow:0 0 0 2px var(--rose-soft,rgba(196,115,127,.25))}
.texsw .swatchtex{display:block;height:52px;background-color:#EFE7E1;
  background-size:var(--w,auto)}
.texsw em{display:block;font-style:normal;font-size:12.5px;font-weight:600;
  padding:7px 9px;color:var(--ink)}
/* ---------- picking the wording above the names ----------
   Each button shows the look rather than describing it, because "Caps +
   script" means nothing until you have seen it. */
.eyepick{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:8px}
.eyesw{border:1.5px solid var(--line);border-radius:10px;padding:0;overflow:hidden;
  background:var(--surface);cursor:pointer;text-align:center;font:inherit}
.eyesw.on{border-color:var(--rose);box-shadow:0 0 0 2px var(--rose-soft,rgba(196,115,127,.25))}
.eyeprev{display:flex;align-items:center;justify-content:center;gap:6px;
  min-height:52px;padding:8px 8px 4px;flex-wrap:wrap;overflow:hidden}
.eyeprev .c{font-size:8.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--gold);font-weight:600}
.eyeprev .s{font-family:'Pinyon Script',cursive;font-size:23px;line-height:1;color:var(--gold)}
.eyeprev .eyenone{color:var(--ink-3);font-size:18px}
/* capitals with rules */
.eyeprev .r{display:flex;align-items:center;gap:5px}
.eyeprev .r b{font-size:8.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);font-weight:600;white-space:nowrap}
.eyeprev .r i{display:block;width:12px;height:1px;background:var(--gold);opacity:.75;flex:none}
/* wide capitals */
.eyeprev .w{font-size:8px;letter-spacing:.34em;text-indent:.34em;text-transform:uppercase;
  color:var(--gold);font-weight:500}
/* script over a rule */
.eyeprev .sr{display:block}
.eyeprev .sr b{display:block;font-family:'Pinyon Script',cursive;font-size:23px;
  line-height:1;color:var(--gold);font-weight:400}
.eyeprev .sr i{display:block;width:28px;height:1px;margin:4px auto 0;
  background:var(--gold);opacity:.75}
/* script over capitals */
.eyeprev .k{display:block}
.eyeprev .k b{display:block;font-family:'Pinyon Script',cursive;font-size:21px;
  line-height:1;color:var(--gold);font-weight:400}
.eyeprev .k u{display:block;text-decoration:none;font-size:7.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--gold);font-weight:600;margin-top:3px}
/* the monogram */
.eyeprev .mo{display:flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--display);font-size:22px;color:var(--gold);line-height:1}
.eyeprev .mo i{display:block;width:1px;height:20px;background:var(--gold);opacity:.8}
.eyesw em{display:block;font-style:normal;font-size:12px;font-weight:600;
  padding:4px 6px 7px;color:var(--ink-2)}

/* ---------- a small row of choices that look like one control ---------- */
.seg{display:flex;gap:4px;background:var(--surface-2);padding:4px;border-radius:9px;
  width:fit-content}
/* white-space:nowrap because these labels are examples of the thing being
   chosen — "2:00 pm" broken over two lines is no longer an example of
   anything, and it made the whole control twice as tall on a phone. */
.seg button{background:none;border:0;border-radius:6px;padding:7px 14px;font:inherit;
  font-size:13.5px;color:var(--ink-2);cursor:pointer;font-variant-numeric:tabular-nums;
  white-space:nowrap}
.seg button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.08)}
.seg.tiny button{padding:5px 8px;display:grid;place-items:center;color:var(--ink-3)}
.seg.tiny button.on{color:var(--ink)}

/* which way a heading or a paragraph faces */
.alrow{display:flex;align-items:center;gap:10px;margin-top:8px}
.allab{font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}

/* a label with a switch on the other end of the same line */
.fllead{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:6px}
.sw.small .track{width:38px;height:21px}
.sw.small .knob{width:15px;height:15px}
.sw.small input:checked + .track .knob{transform:translateX(17px)}

/* ---------- framing the photo across the front page ----------
   The whole picture, with a box over the part that survives. */
.hcropw{position:relative;display:flex;justify-content:center;align-items:center;
  background:var(--surface-2);border:1px solid var(--line);border-radius:11px;
  padding:10px;overflow:hidden;touch-action:none}
.hcropw img{display:block;max-width:100%;max-height:300px;width:auto;height:auto;
  pointer-events:none;border-radius:4px}
.hcropbox{position:absolute;border:2px solid #fff;border-radius:2px;cursor:grab;
  box-shadow:0 0 0 9999px rgba(20,16,24,.52);touch-action:none}
.hcropbox:active{cursor:grabbing}
.hcrz{position:absolute;right:-9px;bottom:-9px;width:18px;height:18px;border-radius:50%;
  background:#fff;border:2px solid var(--rose);cursor:nwse-resize;touch-action:none}

.texamt{display:flex;gap:4px;background:var(--surface-2);padding:4px;
  border-radius:9px;width:fit-content;margin-top:12px}
.texamt button{background:none;border:0;border-radius:6px;padding:6px 13px;
  font:inherit;font-size:13px;color:var(--ink-2);cursor:pointer}
.texamt button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.08)}

/* ---------- mixing your own ---------- */
.swatch.wide{grid-column:1/-1}
.mixer{border-top:1px solid var(--line);margin-top:14px;padding-top:14px}
.fhint{text-transform:none;letter-spacing:0;font-weight:400;color:var(--ink-3,var(--ink-2))}
.colrow{display:flex;gap:8px;align-items:center;margin:0 0 14px}
.colrow input[type=color]{flex:0 0 auto;width:46px;height:40px;padding:3px;
  border:1.5px solid var(--line-2);border-radius:9px;background:var(--surface);cursor:pointer}
.colrow input[type=text]{flex:1;min-width:0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  text-transform:lowercase}
.warn{background:var(--gold-soft,#faf3e0);border-left:3px solid var(--gold,#9a7b2f);
  color:var(--ink);font-size:13.5px;line-height:1.65;padding:10px 12px;border-radius:8px;
  margin:2px 0 12px}
.warn[hidden]{display:none}

/* ---------- blocks, in the editor ---------- */
.blks{list-style:none;padding:0;margin:0 0 14px}
.blk{border:1px solid var(--line);border-radius:11px;padding:10px 12px 12px;margin-bottom:10px}
.blktop{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.blkwhat{flex:1;font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3,var(--ink-2));font-weight:700}
.blk input,.blk textarea{width:100%}
/* The whole photo, not a landscape slice of it. A picture added to a page
   is the couple's own choice of picture — a portrait of the grandmother who
   made the cake should not arrive with her head cut off because the box it
   landed in happened to be wide.

   A real img rather than a background, because an img brings its own shape
   with it: the box becomes whatever the photo is, instead of the
   photo being made to fit the box. */
img.blkimg{display:block;max-width:100%;width:auto;height:auto;max-height:300px;
  border-radius:9px;margin:0 auto 8px;background:var(--surface-2)}
.ghost.wide{width:100%}
.blkadd{display:flex;gap:8px;margin-bottom:10px}
.blkadd .ghost{flex:1;line-height:1.35;padding:9px 6px}
.blkadd .cap{display:block;font-size:10px;opacity:.65;font-weight:400}
.blkadd .ghost[disabled]{opacity:.45;cursor:default}

/* ---------- and on the guest's page ---------- */
.blocks .grule{width:44px;height:1px;background:var(--sgold,var(--gold));margin:22px auto 16px}
.blocks .grule:first-child{margin-top:4px}
.bltitle{font-family:var(--sdisp,var(--display));font-size:20px;text-align:center;
  margin:0 0 10px;color:var(--sink,var(--ink))}
.blocks p{margin:0 0 10px;line-height:1.75}
/* A guest sees the whole photo too — same reasoning as the editor. */
img.blpic{display:block;max-width:100%;width:auto;height:auto;border-radius:12px;
  margin:14px auto;background-color:var(--sline,var(--line))}
span.blpic{display:block;width:100%;aspect-ratio:16/9;border-radius:12px;margin:14px 0;
  background-color:var(--sline,var(--line))}
.faint{opacity:.4}

/* ---------- reordering pages, and the address nudge ---------- */


.nudge{background:var(--gold-soft,#faf3e0);border-left:3px solid var(--gold,#9a7b2f);
  border-radius:8px;padding:12px 14px;margin:0 0 14px}
.nudge p{margin:0;font-size:14px;line-height:1.6}
.nudge .btn.small{margin:0}

/* ---------- the list of pages ---------- */
.pgline{display:flex;align-items:center;gap:9px;padding:7px 0}
.pgline.lock{font-size:15px}
/* 12px so the name starts exactly where the text inside a name box starts */
/* 13 = the name box's 1px border plus its 12px of padding, so a locked name
   starts on exactly the same pixel as a name that can be typed over. */
.pgline.lock b{font-weight:700;color:var(--ink);padding-left:13px}
.pgline.lock .always{margin-left:auto;font-size:12px;color:var(--ink-3);
  letter-spacing:.02em}
/* Not ".ghost" — that is already a kind of button, and it would have dressed
   this up as one. An empty space the width of a handle, nothing more. */
.grip.blank{visibility:hidden;cursor:default}
.pin{flex:0 0 44px;display:grid;place-items:center;color:var(--ink-3)}
.pgline.dragging{opacity:.4}
.pgline.over{box-shadow:0 -2px 0 var(--rose)}

.grip{flex:0 0 auto;width:14px;color:var(--line-2);cursor:grab;line-height:0;
  display:grid;place-items:center}
.grip:active{cursor:grabbing}
.pgline.off .grip{opacity:.5}

/* the switch */
.sw{flex:0 0 auto;position:relative;display:inline-grid;place-items:center;cursor:pointer}
.sw input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.sw .track{width:44px;height:24px;border-radius:99px;background:var(--line-2);
  display:block;position:relative;transition:background .15s ease}
.sw .knob{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.28);transition:transform .15s ease}
.sw input:checked + .track{background:var(--rose)}
.sw input:checked + .track .knob{transform:translateX(20px)}
.sw input:focus-visible + .track{outline:2px solid var(--rose);outline-offset:2px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  white-space:nowrap}

.pgname{flex:1;min-width:0;padding:9px 12px;font-size:14.5px}
.pgline.off .pgname{opacity:.55}

/* ============================================================
   Inspiration, the floor plan, documents and the guest album
   ============================================================ */

/* ---------- a message that fades ---------- */
.toast{position:fixed;left:50%;bottom:22px;transform:translate(-50%,14px);
  max-width:min(440px,calc(100vw - 32px));z-index:80;
  background:var(--ink);color:var(--paper);font-size:14px;line-height:1.45;
  padding:11px 18px;border-radius:999px;box-shadow:0 8px 26px rgba(0,0,0,.22);
  opacity:0;pointer-events:none;transition:opacity .18s ease,transform .18s ease;
  text-align:center}
.toast.on{opacity:1;transform:translate(-50%,0)}
@media (prefers-reduced-motion:reduce){.toast{transition:none}}

.ghost.small{padding:6px 11px;font-size:13px}
.ghost.small.on{border-color:var(--rose);color:var(--rose)}

/* ---------- boards ---------- */
.boards{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 16px}
.bpill{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line-2);
  background:var(--surface);color:var(--ink-2);font:inherit;font-size:13.5px;font-weight:600;
  padding:8px 14px;border-radius:999px;cursor:pointer}
.bpill:hover{border-color:var(--rose)}
.bpill.on{background:var(--rose);border-color:var(--rose);color:#fff}
.bpill span{font-size:12px;font-weight:700;opacity:.75}
.bpill.add{border-style:dashed;color:var(--ink-3)}
.bwrap{display:inline-flex;align-items:center;gap:4px}
.bx{border:0;background:none;color:var(--ink-3);font-size:18px;line-height:1;
  cursor:pointer;padding:4px 6px;border-radius:8px}
.bx:hover{color:var(--stop);background:var(--stop-soft)}
.bnew{display:inline-flex;align-items:center;gap:6px;flex-wrap:wrap}
.bnew input{max-width:180px}

/* ---------- the grid of ideas ---------- */
.icards{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr));gap:14px;margin-bottom:18px}
.icard{position:relative;background:var(--surface);border:1px solid var(--line);
  border-radius:14px;overflow:hidden;cursor:pointer;display:flex;flex-direction:column;
  transition:border-color .15s ease,transform .15s ease}
.icard:hover{border-color:var(--rose)}
.icard:focus-visible{outline:2px solid var(--rose);outline-offset:2px}
.icardx{position:absolute;top:8px;right:8px;z-index:2;background:rgba(255,255,255,.86);
  border-radius:50%;width:26px;height:26px;line-height:1}
.ipic{aspect-ratio:4/3;background-size:cover;background-position:center;
  background-color:var(--surface-2);position:relative}
.ipic.none{display:grid;place-items:center;color:var(--ink-3)}
.ipic.none .ico svg{width:30px;height:30px}
.pcount{position:absolute;left:8px;bottom:8px;background:rgba(0,0,0,.55);color:#fff;
  font-size:11.5px;font-weight:600;padding:3px 8px;border-radius:999px}
.ipal{aspect-ratio:4/3;display:flex}
.ipal span{flex:1}
.ipal.big{aspect-ratio:3/2;border-radius:12px;overflow:hidden}
.ibody{padding:12px 13px 11px;display:flex;flex-direction:column;gap:7px;flex:1}
.ibody b{font-size:15px;line-height:1.3}
.ibody p{margin:0;font-size:13px;color:var(--ink-2);line-height:1.5}
.itags{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.chip2{font-size:11.5px;font-weight:700;letter-spacing:.02em;padding:3px 9px;border-radius:999px;
  background:var(--surface-2);color:var(--ink-2)}
.chip2.good{background:var(--good-soft);color:var(--good)}
.chip2.gold{background:var(--gold-soft);color:var(--gold)}
.chip2.rose{background:var(--rose-soft);color:var(--rose)}
.ipr{font-size:12.5px;font-weight:700;color:var(--ink-2)}
.ifoot{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:auto;
  padding-top:8px;border-top:1px solid var(--line)}
.ibd{font-size:12px;color:var(--ink-3);font-weight:600}

.ifilters{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 14px}
.ifilters select{max-width:210px}
.ishow{font-size:13px;color:var(--ink-2)}

/* ---------- the idea form ---------- */
.ifrm{border-color:var(--rose)}
.iform{display:grid;grid-template-columns:minmax(0,260px) minmax(0,1fr);gap:20px;align-items:start}
.tabs2{display:inline-flex;gap:4px;background:var(--surface-2);padding:4px;border-radius:10px;
  margin-bottom:16px}
.tabs2 button{background:none;border:0;border-radius:7px;padding:8px 16px;font:inherit;
  font-size:13.5px;font-weight:600;color:var(--ink-2);cursor:pointer}
.tabs2 button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(0,0,0,.08)}
.icols{display:grid;grid-template-columns:repeat(5,1fr);gap:6px;margin-top:8px}
.icol{display:flex;flex-direction:column;gap:4px}
.icol input[type=color]{width:100%;height:30px;padding:0;border:1px solid var(--line-2);
  border-radius:7px;background:none;cursor:pointer}
.icol input[type=text]{font-size:10.5px;padding:4px 1px;text-align:center;letter-spacing:-.2px}
.pstrip{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.pth{position:relative;width:52px;height:52px;border-radius:9px;background-size:cover;
  background-position:center;background-color:var(--surface-2)}
.px,.pmv{position:absolute;border:0;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;
  line-height:1;border-radius:50%;width:19px;height:19px;font-size:13px;padding:0}
.px{top:-6px;right:-6px}
.pmv{bottom:2px}
.pmv.l{left:2px}
.pmv.r{right:2px}
.binline{display:flex;gap:6px;flex-wrap:wrap}
.binline input{flex:1 1 120px;min-width:0}

/* ---------- the full-size viewer ---------- */
.lbov{position:fixed;inset:0;z-index:90;background:rgba(14,18,30,.78);
  display:grid;place-items:center;padding:18px;overflow:auto}
.lbox{position:relative;background:var(--surface);border-radius:16px;overflow:hidden;
  width:min(1000px,100%);max-height:calc(100vh - 36px);
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr)}
.lbox.solo{grid-template-columns:minmax(0,1fr)}
.lbx{position:absolute;top:10px;right:12px;z-index:3;border:0;cursor:pointer;
  background:rgba(0,0,0,.5);color:#fff;width:30px;height:30px;border-radius:50%;
  font-size:19px;line-height:1}
.lbmain{background:#0e121e;display:grid;place-items:center;min-height:240px}
.lbimgwrap{position:relative;width:100%;height:100%;display:grid;place-items:center}
.lbimg{max-width:100%;max-height:min(74vh,620px);display:block}
.lbnav{position:absolute;top:50%;transform:translateY(-50%);border:0;cursor:pointer;
  background:rgba(0,0,0,.45);color:#fff;width:38px;height:46px;font-size:26px;line-height:1;
  border-radius:9px}
.lbnav.l{left:8px}
.lbnav.r{right:8px}
.lbcount{position:absolute;bottom:8px;left:50%;transform:translateX(-50%);
  background:rgba(0,0,0,.5);color:#fff;font-size:12px;padding:3px 10px;border-radius:999px}
.lbnone{display:grid;place-items:center;gap:8px;color:#8C97AD;padding:40px}
.lbnone p{margin:0;font-size:13px}
.lbpal{display:flex;width:100%;height:min(60vh,420px)}
.lbpal span{flex:1;display:grid;place-items:end center;padding-bottom:10px}
.lbpal i{font-style:normal;font-size:11px;background:rgba(255,255,255,.85);color:#1B2A4A;
  padding:2px 7px;border-radius:999px}
.lbside{padding:20px;overflow:auto;display:flex;flex-direction:column;gap:10px}
.lbside h3{margin:0;font-family:var(--display);font-size:24px;line-height:1.2}
.lbfacts{margin:6px 0 0;display:grid;gap:10px}
.lbfacts div{display:grid;gap:2px}
.lbfacts dt{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);font-weight:700}
.lbfacts dd{margin:0;font-size:14px;word-break:break-word}
.lbnote{margin:4px 0 0;font-size:14px;color:var(--ink-2);line-height:1.55}
.lbfoot{display:flex;gap:10px;flex-wrap:wrap;margin-top:auto;padding-top:12px}
.lbbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 16px;
  border-top:1px solid var(--line)}
.lbbar div{display:flex;flex-direction:column;margin-right:auto}
.lbbar span{font-size:12.5px;color:var(--ink-3)}

/* ---------- the floor plan ---------- */
.plantop{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px}
.pbtns{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.planwrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,300px);gap:18px;
  align-items:start}
.planbox{background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:14px}
#planvg{width:100%;height:auto;display:block;touch-action:none;user-select:none}
#planvg text{pointer-events:none;font-family:var(--ui)}
.phandle{touch-action:none}
.plannote{text-align:center;margin-top:8px}
#planpos{font-weight:700;color:var(--ink-2)}
.planside .card{margin-bottom:0}
.planside h2{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3);
  font-weight:700;margin:0 0 12px}
.protrow{display:flex;align-items:center;gap:8px}
.protrow input{max-width:110px}
.protrow span{font-size:13px;color:var(--ink-2)}
.protrow button{margin-left:auto}

/* ---------- documents ---------- */
.bitem.doc{align-items:flex-start}
.dicon{flex:0 0 auto;width:36px;height:36px;border-radius:10px;display:grid;place-items:center;
  background:var(--surface-2);color:var(--ink-2);margin-top:1px}
.urlshow{font-size:13px;color:var(--ink-2);word-break:break-all;
  background:var(--surface-2);border-radius:9px;padding:9px 12px}

/* ---------- the guest album ---------- */
.agrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px;margin-bottom:18px}
.apho{position:relative;background:var(--surface);border:1px solid var(--line);
  border-radius:13px;overflow:hidden}
.ashot{display:block;width:100%;aspect-ratio:1/1;border:0;padding:0;cursor:pointer;
  background-size:cover;background-position:center;background-color:var(--surface-2)}
.afav{position:absolute;top:7px;right:7px;border:0;cursor:pointer;font-size:15px;line-height:1;
  width:28px;height:28px;border-radius:50%;background:rgba(255,255,255,.86);color:var(--ink-3)}
.afav.on{color:var(--gold)}
.afoot{display:flex;align-items:center;gap:6px;padding:7px 9px;font-size:12.5px;color:var(--ink-2)}
.afoot span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.qrbox{display:flex;gap:18px;flex-wrap:wrap;align-items:flex-start;
  background:var(--surface-2);border-radius:14px;padding:16px;margin:4px 0 16px}
.qrimg{flex:0 0 auto;background:#fff;padding:10px;border-radius:12px;line-height:0}
.qrimg svg{display:block}
.qrside{flex:1 1 240px;min-width:0}
.qrside b{display:block;font-size:15px;margin-bottom:6px}
.qrside p{margin:0 0 10px;font-size:13.5px;color:var(--ink-2);line-height:1.55}
.qrurl{font-size:12.5px;color:var(--ink-2);word-break:break-all;background:var(--surface);
  border-radius:8px;padding:7px 10px;margin-bottom:10px}

@media (max-width:900px){
  .iform{grid-template-columns:minmax(0,1fr)}
  .planwrap{grid-template-columns:minmax(0,1fr)}
  .lbox{grid-template-columns:minmax(0,1fr);max-height:calc(100vh - 24px);overflow:auto}
  .lbimg{max-height:52vh}
}
@media (max-width:560px){
  .icards{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
  .agrid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:9px}
  .toast{bottom:14px}
}

/* ---------- the album as a guest sees it ---------- */
.galbum .albform{max-width:420px;margin:0 auto 20px;text-align:center}
.galbum .albform .fld{text-align:left}
.gagrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-top:6px}
.gashot{margin:0;position:relative;border-radius:12px;overflow:hidden;
  background:var(--ssink,var(--surface-2))}
.gashot img{display:block;width:100%;aspect-ratio:1/1;object-fit:cover}
.gashot figcaption{position:absolute;left:0;right:0;bottom:0;padding:14px 8px 6px;
  font-size:11.5px;color:#fff;text-align:center;
  background:linear-gradient(to top,rgba(0,0,0,.55),rgba(0,0,0,0))}

/* ---------- looking at one photo, on the wedding website ---------- */
.glb{position:fixed;inset:0;z-index:95;background:rgba(12,14,22,.9);
  display:grid;place-items:center;padding:16px}
.glbin{position:relative;max-width:min(1100px,100%);max-height:calc(100vh - 32px);
  display:grid;place-items:center}
.glbin img{max-width:100%;max-height:calc(100vh - 32px);display:block;border-radius:6px}
.glbx{position:fixed;top:12px;right:14px;z-index:2;border:0;cursor:pointer;
  background:rgba(0,0,0,.5);color:#fff;width:34px;height:34px;border-radius:50%;
  font-size:21px;line-height:1}
.glbnav{position:absolute;top:50%;transform:translateY(-50%);border:0;cursor:pointer;
  background:rgba(0,0,0,.42);color:#fff;width:40px;height:52px;font-size:28px;line-height:1;
  border-radius:9px}
.glbnav.l{left:6px}
.glbnav.r{right:6px}
.glbcount{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);
  background:rgba(0,0,0,.55);color:#fff;font-size:12px;padding:3px 11px;border-radius:999px}
.glbcap{position:absolute;top:10px;left:50%;transform:translateX(-50%);
  background:rgba(0,0,0,.55);color:#fff;font-size:12.5px;padding:3px 11px;border-radius:999px;
  max-width:80%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.gashotb{display:block;width:100%;border:0;padding:0;cursor:pointer;background:none;line-height:0}
.gamine{position:absolute;left:6px;top:6px;border:0;cursor:pointer;font:inherit;font-size:11.5px;
  font-weight:600;padding:4px 9px;border-radius:999px;
  background:rgba(255,255,255,.9);color:#1B2A4A}
.gamine:disabled{opacity:.6;cursor:default}

/* The band of colour in the palette editor IS the button. */
.iswatch{flex:1;border:0;padding:0;cursor:pointer;min-height:100%}
.iswatch:focus-visible{outline:2px solid var(--ink);outline-offset:-3px}

/* A heading INSIDE a card, marking off a second part of the same form —
   a rule above it rather than a box of its own. */
.subhead{font-family:var(--display);font-size:20px;line-height:1.25;font-weight:600;
  margin:26px 0 6px;padding-top:18px;border-top:1px solid var(--line)}
.card > form > .subhead:first-child,.card .subhead:first-child,
.subhead.first{margin-top:0;padding-top:0;border-top:0}

/* A row of buttons under a card, all the same size whatever kind they are.
   A "back" that is visibly smaller than the thing beside it reads as less
   important than it is. */
/* Both kinds of button in one of these rows are built to the same box, so a
   "back" beside a "download" does not read as the lesser of the two. Height is
   set outright rather than left to padding, because a bordered button and an
   unbordered one padded the same are never the same height. */
.pbtns .btn,.pbtns .ghost{min-height:48px;display:inline-flex;align-items:center;
  justify-content:center;padding:0 20px;font-size:15px;font-weight:600;border-radius:9px;
  /* .card .ghost nudges a lone ghost button down by four pixels, which in a row
     of two made one of them sit lower AND stretched the other to match. */
  margin:0}
.prot{touch-action:none}

/* ---------- a budget line you can work on without opening it ---------- */
.bline{flex-wrap:wrap}
.bquick{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;margin-left:auto}
.qf{display:flex;flex-direction:column;gap:3px}
.qf em{font-style:normal;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}
.qf input{width:104px;padding:7px 9px;font-size:14px;text-align:right}
.qf.owe{min-width:86px;align-items:flex-end;justify-content:flex-end}
.qf.owe b{font-size:15px;font-weight:700;line-height:32px}
.qbook{display:flex;flex-direction:column;align-items:center;gap:3px;padding-bottom:5px}
.qbook em{font-style:normal;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3);font-weight:700}
@media (max-width:760px){
  .bquick{margin-left:0;width:100%;gap:10px}
  .qf input{width:88px}
}

/* An invitation waiting to be answered, above whatever screen is open. It is
   the one thing in the app that is asking rather than telling, so it is given
   the accent border a card never otherwise gets. */
.card.invite{border-color:var(--rose);border-width:1.5px}
.card.invite h2{margin-bottom:6px}
.card.invite p{font-size:14.5px;line-height:1.6;color:var(--ink-2);margin:0 0 12px}
.card.invite p b{color:var(--ink)}

/* ---------- the admin side ----------
   One long row per couple, because the useful thing about this screen is
   scanning it: names, address, what they are using, all on the same line. The
   reason box and the read-only panel drop underneath the row they belong to
   rather than opening somewhere else, so you never lose your place. */
.admrow{flex-wrap:wrap;align-items:flex-start}
.admrow .gname{flex:1 1 280px}
.admrow .gmeta{margin-top:3px;line-height:1.45}
.admacts{display:flex;gap:6px;flex-wrap:wrap;flex:0 0 auto}
.admrow .admask,
.admrow .admin-inside{flex:1 1 100%;margin:12px 0 2px}
.admin-inside{background:var(--surface-2)}
.admin-inside .tinyhead{margin:16px 0 6px}
.admlines{list-style:none;margin:0;padding:0;font-size:13.5px;line-height:1.65}
.admlines li{padding:1px 0;overflow-wrap:anywhere}
.admlines .note{display:inline;font-size:12px}
.tally dd.small{font-family:var(--ui);font-size:15px;font-weight:600;line-height:1.3;
  overflow-wrap:anywhere}

/* An account on its way out. Not alarming, not hidden — the date is the thing
   somebody needs to read, so the date is what is emphasised. */
.stat.going{background:var(--stop-soft);color:var(--stop)}

.admlog .who{flex:0 0 auto;text-align:right;max-width:40%;overflow-wrap:anywhere}

@media(max-width:560px){
  .admrow .admacts{width:100%}
  .admrow .admacts .ghost{flex:1}
  .admlog .who{width:100%;text-align:left;max-width:none}
}

/* ---------- the admin filters ---------- */
.admfil{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  align-items:end}
.admfil .tabs{margin:0}
.admfil .tabs button{padding:8px 10px;font-size:13px;white-space:nowrap}
.admfil select,.admfil input{width:100%}
#admCount{margin:0 0 12px}

/* ---------- graphs ----------
   One hue per graph, checked against the page in both light and dark rather
   than picked by eye: the dark step is a genuinely different colour, not the
   light one flipped, because the light rose loses its saturation against a
   dark ground and reads as grey. */
:root{ --chart:#C4737F }
@media (prefers-color-scheme:dark){ :root{ --chart:#D4708A } }

.chart{position:relative;margin:4px 0 2px}
/* The drawing takes whatever width the card gives it and keeps its shape.
   Without this it is scaled to fit its HEIGHT instead and sits letterboxed in
   the middle of a wide card with empty space either side. */
.chart svg{display:block;width:100%;height:auto;overflow:visible}
.chart .col{fill:var(--chart)}
/* Hairline, solid, and one step off the surface. A grid you notice is a grid
   competing with the data. */
.chart .grid{stroke:var(--line);stroke-width:1}
.chart .axis{stroke:var(--line-2);stroke-width:1}
/* Text wears text colours, never the data colour — the mark beside it carries
   the identity. */
.chart .tick{fill:var(--ink-3);font:500 10px var(--ui)}
.chart .tick.lab{fill:var(--ink-2);font-size:11px}
.chart .val{fill:var(--ink);font:700 11px var(--ui)}
.chart .hit{fill:transparent;cursor:default}
.chart .hit:hover,.chart .hit:focus{fill:var(--surface-2);opacity:.55;outline:none}

.chtip{position:absolute;pointer-events:none;z-index:5;
  background:var(--ink);color:var(--paper);font:600 12px var(--ui);
  padding:5px 9px;border-radius:7px;white-space:nowrap;
  box-shadow:0 4px 14px rgba(0,0,0,.18)}

/* Every number in every graph, in plain text. Hovering is not available on a
   phone at all, so nothing may be reachable only by hovering. */
.chnums{margin-top:10px}
.chnums summary{font-size:12.5px;color:var(--ink-2);cursor:pointer}
.chnums table{width:100%;border-collapse:collapse;margin-top:8px;font-size:13px}
.chnums th,.chnums td{text-align:left;padding:5px 8px;border-bottom:1px solid var(--line)}
.chnums th{font:700 10px var(--ui);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3)}
.chnums td:last-child,.chnums th:last-child{text-align:right;
  font-variant-numeric:tabular-nums}

/* ---------- the privacy notice and the terms ----------
   A long document read once, carefully, often on a phone and sometimes by
   somebody who is annoyed. So: one narrow column, generous line height, real
   headings, and tables that do not run off the side of the screen. */
.legalpage{background:var(--paper)}
.legalhead{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;padding:16px 22px;border-bottom:1px solid var(--line);
  background:var(--surface)}
.legalback{font-family:var(--display);font-size:19px;font-weight:600;color:var(--ink);
  text-decoration:none}
.legalhead nav{display:flex;gap:16px}
.legalhead nav a{font-size:13.5px;color:var(--ink-2);text-decoration:none}
.legalhead nav a[aria-current]{color:var(--rose);font-weight:700}

.legal{max-width:720px;margin:0 auto;padding:30px 22px 60px}
.legal h1{font-family:var(--display);font-size:38px;font-weight:600;margin:0 0 10px;
  line-height:1.1}
.legal h2{font-family:var(--display);font-size:25px;font-weight:600;
  margin:38px 0 10px;line-height:1.2}
.legal h3{font-size:14px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--ink-2);margin:24px 0 8px}
.legal p{font-size:15.5px;line-height:1.72;margin:0 0 14px;color:var(--ink)}
.legal .stand{font-size:17px;color:var(--ink-2);margin-bottom:10px}
.legal .meta{font-size:12.5px;color:var(--ink-3);margin-bottom:26px}
.legal ul{margin:0 0 16px;padding-left:20px}
.legal li{font-size:15.5px;line-height:1.72;margin-bottom:7px}
.legal a{color:var(--rose)}
.legal .strong{font-weight:600}
.legal .note{font-size:13.5px;color:var(--ink-2);line-height:1.62}
.legal .card{margin:18px 0 22px}
.legal .card h3{margin-top:0}
.legal .tldr ul{margin-bottom:12px}

/* Two columns, the left one naming the thing and the right one explaining it.
   On a phone they stack, because a 40%/60% split at 360px is two columns of
   broken words. */
.legal .lt{width:100%;border-collapse:collapse;margin:0 0 18px}
.legal .lt th,.legal .lt td{text-align:left;vertical-align:top;padding:11px 0;
  border-top:1px solid var(--line);font-size:14.5px;line-height:1.62}
.legal .lt tr:first-child th,.legal .lt tr:first-child td{border-top:0}
.legal .lt th{width:34%;padding-right:20px;font-weight:700;color:var(--ink-2)}
@media(max-width:620px){
  .legal h1{font-size:31px}
  .legal h2{font-size:22px}
  .legal .lt th,.legal .lt td{display:block;width:auto;padding:0}
  .legal .lt th{border-top:1px solid var(--line);padding-top:12px;margin-bottom:2px}
  .legal .lt td{padding-bottom:12px}
  .legal .lt tr:first-child th{border-top:0}
}

/* Impossible to mistake for the document, and impossible to miss. It is only
   ever on screen while the company's own details are still unfilled. */
.gapwarn{border-color:var(--stop);background:var(--stop-soft)}
.gapwarn h2{margin:0 0 8px;color:var(--stop);font-size:21px}
.gapwarn p{margin:0 0 6px}

/* ---------- agreeing, on the way in ---------- */
.agreebox{display:flex;gap:10px;align-items:flex-start;margin:4px 0 14px;
  font-size:13.5px;line-height:1.55;color:var(--ink-2);cursor:pointer}
.agreebox input{margin:2px 0 0;width:17px;height:17px;flex:0 0 auto;accent-color:var(--rose)}
.agreebox a{color:var(--rose)}
.gatelegal{text-align:center;font-size:12.5px;color:var(--ink-3);margin:14px 0 0;
  line-height:1.6}
.gatelegal a{color:var(--ink-2)}
.termscard .gbtns{flex-wrap:wrap}
.foot a{color:inherit}

/* ---------- what a guest is told, where they are asked ----------
   In the couple's own colours rather than BrideHub's, because it sits on their
   page. Quiet, but not hidden: it is the only thing on the page that tells a
   guest what happens to what they just typed. */
.gprivacy{font-size:12px;line-height:1.6;margin:14px 0 0;
  color:var(--sink,var(--ink-3));opacity:.72;text-align:center}
.gprivacy a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.gft .gcr a{margin-left:8px;color:inherit;opacity:.8;text-decoration:underline;
  text-underline-offset:2px}

/* Closing an account for good. Red, because it is the one button in BrideHub
   that cannot be undone — and deliberately not the first thing on the card. */
.btn.danger{background:var(--stop);border-color:var(--stop)}
.btn.danger:hover{filter:brightness(.94)}
