/* Seatwise design tokens.
   Signature idea: the product's real output is a physical object — an escort
   card / table tag someone finds at the door — so the visual language borrows
   from fine stationery and drafting tools (the planner's working view) rather
   than "warm invitation" softness everywhere. Deliberately not the cream+
   high-contrast-serif+terracotta combination this category defaults to. */
:root{
  --paper:#EDEBE1;   /* floor sheet — cool stone, not cream */
  --chrome:#FBFAF4;  /* header, panels, cards, tables */
  --desk:#E3E0D3;    /* stage behind the sheet */
  --panel-line:#D7D2C1;
  --hairline:#E3E0D3;
  --row-line:#ECE9DE;
  --grid:#DAD5C5;
  --field:#F5F3E9; --field-line:#D5CFBC;
  --ink:#1B231F; --ink-2:#2B332E; --body:#454F49;
  --muted:#5E685F; --soft:#7B857B; --faint:#9AA096; --ghost:#ABB0A3; --disabled:#C7C7BA;
  --accent:#A97C2F; --accent-ink:#8A6423; --accent-wash:#F3ECDC; --accent-line:#DEC993;
  --gold:#96843B; --danger:#A23B2E; --danger-deep:#7A2B20;
  --danger-wash:#F7ECE9; --danger-line:#E3C7C0; --blocked-wash:#F3E4DF;
  --ok:#3C5442; --ok-wash:#EEF1EB;
  --dark:#17201C; --alarm:#4F1F17;

  --crew-1:#8B5E3C; --crew-2:#6E7A45; --crew-3:#3F6B6B;
  --crew-4:#5B5F80; --crew-5:#8A5570; --crew-6:#A05F6E;

  --ui:"IBM Plex Sans",-apple-system,"Helvetica Neue",Arial,sans-serif;
  --display:Fraunces,Georgia,serif;
  --mono:"IBM Plex Mono",ui-monospace,Menlo,monospace;

  --r-xs:6px; --r-sm:7px; --r:8px; --r-md:9px; --r-lg:12px; --r-pill:20px;
  --shadow-panel:0 8px 24px -14px #1b231f66;
  --shadow-pop:0 20px 44px -16px #1b231f66;
  --shadow-sheet:0 2px 0 #d7d2c1, 0 24px 60px -30px #1b231f55;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;background:#DEDACC;color:var(--ink);
  font-family:var(--ui);-webkit-font-smoothing:antialiased;
}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-ink)}
button{font-family:inherit;cursor:pointer}
input,select,textarea{font-family:inherit}
.sw-noprint{}
.sw-print-header,.sw-print-roster{display:none}
body.sw-nosel, body.sw-nosel *{user-select:none !important}

/* ---------- generic building blocks ---------- */
.btn{
  border:none;border-radius:var(--r);padding:10px 16px;font-size:13.5px;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  min-height:38px;
}
.btn-primary{background:var(--accent);color:var(--chrome)}
.btn-primary:hover{background:var(--accent-ink);color:var(--chrome)}
.btn-primary:disabled{background:#9C8A63;cursor:default}
.btn-secondary{background:var(--chrome);border:1px solid var(--field-line);color:var(--ink-2)}
.btn-dark{background:var(--ink);color:var(--paper)}
.btn-danger{background:var(--danger-wash);border:1px solid var(--danger-line);color:var(--danger)}
.btn-ghost{background:transparent;border:none;color:var(--body)}

.field{display:flex;flex-direction:column;gap:5px}
.field > span, label.field-label{
  font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--soft);
}
.field input, .field select, .field textarea, input.sw-input, select.sw-input{
  border:1px solid var(--field-line);background:var(--chrome);border-radius:var(--r-sm);
  padding:10px 11px;font-size:13.5px;outline:none;color:var(--ink);
}
.field input:focus, .field select:focus, .field textarea:focus{border-color:var(--accent)}

.card{background:var(--chrome);border:1px solid var(--panel-line);border-radius:var(--r-lg)}
.eyebrow{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--crew-1)}
.pill{border-radius:var(--r-pill);padding:5px 11px;font-size:11.5px;display:inline-flex;align-items:center;gap:6px}

.avatar{
  border-radius:50%;background:#E5E1D3;display:grid;place-items:center;
  font-family:var(--display);color:#4C554C;flex:none;
}

/* ---------- site header (marketing/auth/dashboard) ---------- */
.sw-nav{display:flex;align-items:center;gap:22px;padding:16px 28px;border-bottom:1px solid var(--hairline);background:var(--chrome)}
/* The wordmark carries the logo mark itself (a round table with one seat
   filled in brass) rather than an abstract dot, so the brand is the same
   object everywhere: nav, favicon, social avatar, share card. */
/* No flex `gap` here: "Seating" and the .brand-tail "Sorted" are two separate flex
   items, so a gap would open a space through the middle of the name. The mark
   spaces itself with a margin instead. */
.sw-wordmark{
  font-family:var(--display);font-size:19px;font-weight:600;display:inline-flex;
  align-items:center;color:var(--ink);letter-spacing:-.015em;
}
.sw-wordmark .dot{
  width:1.05em;height:1.05em;flex:none;transform:none;border-radius:0;background:none;
  margin-right:9px;
  background-image:url("../img/logo-mark.svg");background-size:contain;
  background-repeat:no-repeat;background-position:center;
  order:-1;  /* mark leads the wordmark */
}
.sw-wordmark .brand-tail{color:var(--accent);font-weight:400}
.sw-nav .spacer{flex:1}
.sw-nav a.navlink{font-size:13px;color:var(--body)}

/* ---------- animations ---------- */
@keyframes swland{from{opacity:0;transform:scale(.4) translateY(-14px)}to{opacity:1;transform:none}}
@keyframes swpulse{0%,100%{box-shadow:0 0 0 0 #A23B2E44}50%{box-shadow:0 0 0 6px #A23B2E00}}
/* a solid, fully-opaque ring at all times (previously both the ring and its
   glow faded in/out together, which read as a faint flicker rather than an
   obvious "this seat has a hard conflict" signal) — only the soft outer glow
   breathes, the red ring itself never fades. */
@keyframes swglow{0%,100%{box-shadow:0 0 0 3px var(--danger),0 0 9px 2px #A23B2E4d}50%{box-shadow:0 0 0 3px var(--danger),0 0 13px 3px #A23B2E70}}
@keyframes swalarm{0%{box-shadow:0 0 0 0 #A23B2E00}50%{box-shadow:0 0 0 9px #A23B2E33,0 0 22px 4px #A23B2E55}100%{box-shadow:0 0 0 0 #A23B2E00}}
@keyframes swshake{0%,100%{transform:translateX(0)}25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}
/* opacity-only: several elements that use .sw-fade-in (the diff bar, report
   panel, alarm bar) also center themselves with their own transform:translateX(),
   and CSS transform is a single property — a translateY here would silently
   replace that centering transform for the animation's duration. The diff bar
   re-plays this animation on every 800ms solver poll, so that used to be a
   very visible "jump right, then snap back" every single poll. */
@keyframes swfade{from{opacity:0}to{opacity:1}}
@keyframes swspin{to{transform:rotate(360deg)}}

.sw-landing{animation:swland .5s var(--delay,0s) both}
.sw-pulse-dot{animation:swpulse 2s ease-in-out infinite}
.sw-glow{animation:swglow 1.8s ease-in-out infinite;z-index:5}
.sw-alarm{animation:swalarm .45s ease-out 2, swshake .42s ease-in-out;z-index:6}
.sw-fade-in{animation:swfade .16s ease}
.sw-spin{animation:swspin .7s linear infinite}

/* ---------- planner shell ---------- */
.sw-app{height:100vh;display:flex;flex-direction:column}
.sw-header{
  height:54px;background:var(--chrome);border-bottom:1px solid var(--panel-line);
  padding:0 14px;display:flex;align-items:center;gap:18px;z-index:40;flex:none;
}
.sw-header .divider{width:1px;height:24px;background:var(--hairline)}
.sw-event-block{display:flex;flex-direction:column;line-height:1.2;overflow:hidden}
.sw-event-block .name{font-family:var(--display);font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sw-event-block .meta{font-size:10.5px;text-transform:uppercase;letter-spacing:.04em;color:var(--soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width: 1000px){ .sw-event-block, .sw-seated-counter{display:none} }

.sw-tabs{display:flex;padding:3px;background:#EBE7DA;border:1px solid var(--hairline);border-radius:9px;gap:2px}
.sw-tabs a{padding:6px 12px;border-radius:6px;font-size:12.5px;color:var(--body)}
.sw-tabs a.active{background:var(--chrome);box-shadow:0 1px 3px #1b231f22;color:var(--ink)}

.sw-seated-counter{font-family:var(--mono);font-size:11px;color:var(--muted)}

.sw-conflict-pill{cursor:pointer;border:1px solid transparent}
.sw-conflict-pill .dot{width:7px;height:7px;border-radius:50%}
.sw-conflict-pill.sev-blocked{background:#7A2B2012;border-color:#7A2B2044;color:#7A2B20}
.sw-conflict-pill.sev-blocked .dot{background:#7A2B20}
.sw-conflict-pill.sev-high{background:#A23B2E12;border-color:#A23B2E44;color:#A23B2E}
.sw-conflict-pill.sev-high .dot{background:#A23B2E}
.sw-conflict-pill.sev-soft{background:#96843B12;border-color:#96843B44;color:#96843B}
.sw-conflict-pill.sev-soft .dot{background:#96843B}
.sw-conflict-pill.sev-clear{background:#3C544212;border-color:#3C544244;color:#3C5442}
.sw-conflict-pill.sev-clear .dot{background:#3C5442}

.sw-body{flex:1;display:flex;min-height:0}
.sw-side{background:var(--chrome);border-color:var(--panel-line);flex:none;display:flex;flex-direction:column;min-height:0;transition:width .15s ease}
.sw-guest-panel{width:292px;border-right:1px solid var(--panel-line)}
.sw-inspector{width:318px;border-left:1px solid var(--panel-line)}
.sw-side.collapsed{width:34px;min-width:34px}
.sw-side .sw-panel-content{display:flex;flex-direction:column;min-height:0;flex:1;width:100%;overflow:hidden}
.sw-side.collapsed .sw-panel-content{display:none}

/* the tiny ‹/› text-arrow toggle used to display:none the whole panel — including
   its own reopen button — so a collapsed panel had no visible way back. Now the
   panel stays mounted at a slim, permanent width with this tab in its place. */
.sw-panel-collapse-btn{
  background:transparent;border:none;border-radius:6px;padding:5px;color:var(--soft);
  display:grid;place-items:center;cursor:pointer;flex:none;
}
.sw-panel-collapse-btn:hover{background:#EBE7DA;color:var(--ink-2)}
.sw-edge-tab{
  display:none;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  width:100%;height:100%;background:var(--chrome);border:none;color:var(--soft);
  cursor:pointer;padding:16px 0;
}
.sw-edge-tab:hover{background:#EFEBDF;color:var(--ink-2)}
.sw-edge-tab span{writing-mode:vertical-rl;font-size:10.5px;letter-spacing:.05em;text-transform:uppercase}
.sw-side.collapsed .sw-edge-tab{display:flex}
.sw-stage-wrap{flex:1;min-width:420px;background:var(--desk);overflow:hidden;position:relative;touch-action:none}
.sw-stage-wrap.zoomed-in .sw-seat .first-name{display:block}
.sw-stage-wrap.tool-pan{cursor:grab}
.sw-stage-wrap.panning{cursor:grabbing}
.sw-stage-wrap.panning *{cursor:grabbing !important}

/* guest list */
.sw-guest-header{padding:13px 14px 10px;border-bottom:1px solid var(--hairline);display:flex;flex-direction:column;gap:9px}
.sw-guest-label{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--soft);display:flex;align-items:center;justify-content:space-between}
.sw-search{border:1px solid var(--field-line);background:var(--field);border-radius:7px;padding:8px 10px;font-size:12.5px;width:100%;outline:none}
.sw-chips{display:flex;gap:6px}
.sw-chip{border-radius:var(--r-pill);padding:4px 9px;font-size:11px;background:#EBE7DA;border:1px solid var(--hairline);color:var(--body);cursor:pointer;transition:background var(--t-fast) var(--ease-out),border-color var(--t-fast) var(--ease-out),color var(--t-fast) var(--ease-out)}
.sw-chip:hover{border-color:var(--accent-line)}
.sw-chip.active,.sw-chip:has(input:checked){background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent)}
.sw-chip-count{font-family:var(--mono);font-size:10px;opacity:.7;margin-left:1px}
.sw-chip:has(input:checked) .sw-chip-count{opacity:1}
/* keyboard users tab onto the hidden radio, so show the ring on the label */
.sw-chip:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.sw-guest-list{flex:1;overflow-y:auto;padding:6px}
.sw-guest-row{
  display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:7px;cursor:grab;
  border-left:2px solid transparent;
}
.sw-guest-row:hover{background:#F1EEE2;border-left-color:var(--accent)}
.sw-guest-row:active{cursor:grabbing}
.sw-crew-bar{width:3px;height:26px;border-radius:2px;flex:none}
.sw-guest-avatar{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-family:var(--display);font-size:11px;flex:none;position:relative}
.sw-guest-name{font-family:var(--display);font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sw-guest-name.declined{color:var(--ghost)}
.sw-guest-meta{font-size:10px;color:#7E8378}
.sw-guest-main{flex:1;min-width:0;display:flex;flex-direction:column}
.sw-conflict-dot{width:6px;height:6px;border-radius:50%;position:absolute;right:-1px;bottom:-1px}
.sw-seat-tag{font-family:var(--mono);font-size:10px;color:var(--soft)}
.sw-seat-tag.conflicted{color:var(--danger)}
.sw-guest-footer{padding:9px 12px;font-size:10.5px;color:#7E8378;border-top:1px solid var(--hairline)}

/* stage / floor sheet */
/* the whole world is CSS-scaled by the camera; promoting it to its own compositor
   layer (will-change) makes the browser scale one rasterized bitmap on zoom instead
   of re-rasterizing hairline gradients every frame, which is what caused the grid to
   shimmer/misrender during zoom. a dot pattern also resists that moiré far better
   than 1px crossing lines. */
.sw-world{transform-origin:0 0;position:absolute;left:0;top:0;will-change:transform;backface-visibility:hidden}
.sw-sheet{
  width:2600px;height:1800px;background:var(--paper);position:relative;
  background-image:radial-gradient(circle at center, var(--grid) 1.3px, transparent 1.3px);
  background-size:40px 40px;background-position:-0.5px -0.5px;
  border:1px solid var(--panel-line);box-shadow:var(--shadow-sheet);
}
.sw-feature{position:absolute;border:1.5px solid #D2CAB2;border-radius:10px;display:grid;place-items:center}
.sw-feature .label{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:#7C8172}
.sw-feature.kind-stage{background:#E5E0D0;border-radius:10px 10px 3px 3px}
.sw-feature.kind-floor{background:#ECE6D6}
.sw-feature.kind-bar{background:#E4DFD0}
.sw-feature.kind-door{background:#EBE7DA;border-style:dashed}
.sw-feature.kind-plain{background:#EBE7DA}

.sw-table-wrap{position:absolute}
.sw-table-body{
  background:var(--chrome);border:1.5px solid #D6D0BE;box-shadow:0 6px 18px -14px #1b231f88;
  position:absolute;
}
.sw-table-body.selected{border-color:var(--accent);border-width:2px;box-shadow:0 10px 26px -14px #A97C2F88}
.sw-table-body.conflicted{border-color:#D3AFA6}
.sw-table-body.shape-circle{border-radius:50%}
.sw-table-body.shape-rectangle{border-radius:12px}
.sw-table-body.shape-row{border-radius:6px}
.sw-table-body.shape-booth{border-radius:12px}

/* The label sits in the middle of the table top, the way a real table number
   card does — the wrap's origin (left:0/top:0) is the table centre, so a
   -50%/-50% translate lands it dead centre regardless of shape or size.
   No background: the table surface underneath already provides the card. */
.sw-table-label{
  position:absolute;display:flex;flex-direction:column;align-items:center;gap:2px;
  text-align:center;pointer-events:none;transform:translate(-50%,-50%);white-space:nowrap;
}
.sw-table-label .name{font-family:var(--display);font-size:13px;font-weight:500;color:var(--ink-2);line-height:1.1}
.sw-table-label .count{font-family:var(--mono);font-size:9.5px;color:var(--soft);letter-spacing:.04em}
.sw-table-label .count.full{color:var(--ok)}
.sw-table-label .crew-mix{width:46px;height:3px;border-radius:2px;display:flex;overflow:hidden;background:var(--hairline)}
.sw-table-label .conflict-line{font-size:9.5px;font-weight:500}
.sw-table-label .conflict-line.high{color:var(--danger)}
.sw-table-label .conflict-line.soft{color:var(--gold)}


.sw-seat{
  width:30px;height:30px;border-radius:50%;position:absolute;margin:-15px 0 0 -15px;
  display:grid;place-items:center;cursor:pointer;
}
.sw-seat.empty{background:#EBE7DA;border:1px dashed #CDC5B0}
.sw-seat.occupied{background:var(--chrome);border:1.5px solid var(--crew-1)}
.sw-seat.sw-drop-target{
  background:var(--accent-wash);border:2px solid var(--accent);
  box-shadow:0 0 0 4px #A97C2F26;transform:scale(1.12);
  transition:transform .1s ease,box-shadow .1s ease;
}

/* custom drag image (see planner.js buildDragGhost) — rendered off-screen,
   captured via setDragImage, then removed; never actually seen in place. */
.sw-drag-ghost{
  position:fixed;top:-999px;left:-999px;display:flex;align-items:center;gap:7px;
  padding:6px 12px 6px 6px;background:var(--ink);color:var(--paper);border-radius:20px;
  font-family:var(--ui);font-size:12.5px;white-space:nowrap;box-shadow:var(--shadow-pop);
}
.sw-drag-ghost-avatar{
  width:22px;height:22px;border-radius:50%;background:var(--accent);color:var(--chrome);
  display:grid;place-items:center;font-family:var(--display);font-size:10px;flex:none;
}
.sw-seat .initials{font-family:var(--display);font-size:11px;color:#26302A}
.sw-seat .glyph{position:absolute;top:-3px;right:-3px;font-size:9px;color:var(--gold)}
.sw-seat.sw-proposed{box-shadow:0 0 0 2px #A97C2F88}
.sw-seat .first-name{
  position:absolute;top:32px;left:50%;transform:translateX(-50%);white-space:nowrap;
  font-family:var(--display);font-size:10px;color:var(--muted);display:none;
}

/* tool dock / view dock */
.sw-tool-dock{
  position:absolute;left:14px;top:50%;transform:translateY(-50%);background:var(--chrome);
  border:1px solid var(--panel-line);border-radius:var(--r-lg);padding:6px;box-shadow:var(--shadow-panel);
  display:flex;flex-direction:column;gap:4px;z-index:20;
}
.sw-tool-btn{
  width:48px;height:48px;border:none;background:transparent;border-radius:var(--r-sm);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;color:var(--body);
}
.sw-tool-btn svg{stroke:var(--body)}
.sw-tool-btn .lbl{font-size:8.5px;text-transform:uppercase;letter-spacing:.05em}
.sw-tool-btn.active{background:var(--accent-wash)}
.sw-tool-btn.active svg{stroke:var(--accent)}
.sw-tool-btn.active .lbl{color:var(--accent)}
.sw-tool-btn:hover{background:#EFEBDF}

.sw-view-dock{
  position:absolute;right:14px;bottom:14px;background:var(--chrome);border:1px solid var(--panel-line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-panel);display:flex;align-items:center;gap:2px;padding:4px;z-index:20;
}
.sw-view-dock button{border:none;background:transparent;padding:7px 9px;border-radius:var(--r-sm);font-size:12px;color:var(--body)}
.sw-view-dock button:hover{background:#EFEBDF}
.sw-view-dock button.disabled{color:var(--disabled);cursor:default}
.sw-view-dock .zoom-pct{font-family:var(--mono);font-size:11px;min-width:38px;text-align:center}
.sw-view-dock .vd-divider{width:1px;height:18px;background:var(--hairline)}

/* proposal / diff bar */
.sw-diff-bar{
  /* was translateX(calc(-50% + 38px)) — that fixed +38px was tuned for one
     content width (the "proposed plan" state, wide, with buttons) but this bar
     is reused for the narrower "Solving…" state too, so every poll that swapped
     between the two visibly jumped sideways as the bar's own width changed
     under an off-center transform. Pure -50% centers correctly at any width. */
  position:absolute;left:50%;bottom:62px;transform:translateX(-50%);background:var(--dark);
  color:var(--paper);border-radius:var(--r-lg);padding:12px 16px;display:flex;align-items:center;gap:16px;z-index:30;
  box-shadow:var(--shadow-pop);
}
.sw-diff-bar .headline{font-size:13px}
.sw-diff-bar .sub{font-size:11px;color:#B8BCA9}
.sw-diff-why{
  display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--paper);
  background:#ffffff1a;border:1px solid #ffffff33;border-radius:var(--r-pill);
  padding:7px 12px;cursor:pointer;white-space:nowrap;
}
.sw-diff-why:hover{background:#ffffff2b}
.sw-diff-why .dot{width:8px;height:8px;border-radius:50%;flex:none}

.sw-report-panel{
  position:absolute;left:50%;bottom:126px;transform:translateX(-50%);background:var(--chrome);
  border:1px solid var(--panel-line);border-radius:var(--r-lg);width:min(560px, 100% - 190px);
  max-height:60vh;overflow-y:auto;overscroll-behavior:contain;z-index:31;box-shadow:var(--shadow-pop);padding:18px 20px;
}
.sw-score-chip{background:#EBE7DA;border-radius:10px;padding:8px 14px;text-align:center}
.sw-score-chip .score{font-family:var(--display);font-size:23px}
.sw-score-chip .lbl{font-size:9px;text-transform:uppercase;color:var(--soft)}
.sw-statbar-track{height:6px;background:#E5E1D2;border-radius:4px;overflow:hidden}
.sw-statbar-fill{height:100%}

/* alarm bar */
.sw-alarm-bar{
  position:absolute;left:50%;top:14px;transform:translateX(-50%);background:var(--alarm);color:var(--paper);
  border-radius:var(--r-lg);padding:10px 16px;display:flex;align-items:center;gap:12px;z-index:35;box-shadow:var(--shadow-pop);
  font-size:12.5px;
}

/* context menus */
/* #sw-menu (no class, id only) is the element planner.js actually moves via
   style.left/top/display — it's an empty wrapper <div> in index.html, and its
   *inner* content (the .sw-menu-class'd div rendered by _menu.html) is what
   used to carry position:fixed instead. Styling the wrong element meant
   left/top were being set on a position:static box, where they do nothing —
   the menu just rendered wherever it fell in normal document flow (the top of
   #sw-stage), which is exactly the "menu opens in the top-left" bug. */
#sw-menu{position:fixed;z-index:50}
.sw-menu{
  background:var(--chrome);border:1px solid var(--panel-line);border-radius:var(--r-md);
  padding:5px;min-width:212px;box-shadow:var(--shadow-pop);
}
.sw-menu .item{cursor:pointer}
.sw-menu .title{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--faint);padding:6px 9px 4px}
.sw-menu .item{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 9px;border-radius:6px;font-size:12.5px;color:var(--ink-2)}
.sw-menu .item:hover{background:#EFEBDF}
.sw-menu .item.destructive{color:var(--danger)}
.sw-menu .item .shortcut{font-family:var(--mono);font-size:10px;color:var(--ghost)}
.sw-menu .group-divider{border-top:1px solid #E6E2D2;margin:4px 0}

/* inspector */
.sw-inspector-body{padding:14px;overflow-y:auto;flex:1;display:flex;flex-direction:column;gap:16px}
.sw-inspector .section-label{font-size:10.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--soft)}
.sw-health-row{display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid #E7E3D4;font-size:12.5px}
.sw-health-row .value{font-family:var(--mono)}
.sw-issue-row{border-radius:8px;padding:9px 10px;display:flex;gap:8px;align-items:flex-start;cursor:pointer}
.sw-issue-row .dot{width:7px;height:7px;border-radius:50%;margin-top:4px;flex:none}
.sw-issue-row.sev-blocked{background:var(--blocked-wash);border:1px solid #DCC0B8}
.sw-issue-row.sev-high{background:var(--danger-wash);border:1px solid var(--danger-line)}
.sw-issue-row.sev-soft{background:#F0ECDF;border:1px solid #DFD8B9}
.sw-issue-row.sev-clear{background:var(--ok-wash);border:1px solid #D6DFD3}

/* misc */
.sw-crew-legend{display:flex;flex-direction:column;gap:6px}
.sw-crew-legend-row{display:flex;align-items:center;gap:8px;font-size:12px}
.sw-crew-legend-row .swatch{width:9px;height:9px;border-radius:50%}
.sw-crew-legend-row .count{margin-left:auto;font-family:var(--mono);color:var(--muted)}

/* overlays (guests/rules views) */
.sw-overlay{position:fixed;inset:0;background:#1B231Ff2;z-index:60;overflow-y:auto;padding:40px 20px}
.sw-overlay-col{max-width:1080px;margin:0 auto}
.sw-overlay-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}
.sw-overlay-title{font-family:var(--display);font-size:24px;color:var(--paper)}
table.sw-table{width:100%;border-collapse:collapse;background:var(--chrome);border-radius:var(--r-lg);overflow:hidden}
table.sw-table thead th{background:#EBE7DA;text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--soft);padding:10px 14px}
table.sw-table tbody td{padding:10px 14px;border-top:1px solid var(--row-line);font-size:13px;vertical-align:middle}
table.sw-table tbody tr:hover{background:#F3F0E4}
table.sw-table thead th[data-sort]{cursor:pointer;user-select:none;position:relative;padding-right:20px}
table.sw-table thead th[data-sort]:hover{color:var(--ink-2)}
table.sw-table thead th[data-sort]::after{content:"↕";position:absolute;right:7px;color:var(--faint);font-size:10px}
table.sw-table thead th[data-sort][data-sort-dir="asc"]::after{content:"↑";color:var(--accent)}
table.sw-table thead th[data-sort][data-sort-dir="desc"]::after{content:"↓";color:var(--accent)}

.sw-summary-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:20px}
.sw-summary-card{background:var(--chrome);border-radius:var(--r-lg);padding:16px}
.sw-summary-card .count{font-family:var(--display);font-size:26px}
.sw-summary-card .lbl{font-size:11px;text-transform:uppercase;color:var(--soft)}

/* ---------- account dropdown ---------- */
.sw-account{position:relative}
.sw-account > button.avatar{border:none;padding:0}
.sw-account > button.avatar:hover{box-shadow:0 0 0 2px var(--accent-line)}
.sw-dropdown{
  position:absolute;top:calc(100% + 8px);right:0;background:var(--chrome);
  border:1px solid var(--panel-line);border-radius:var(--r-md);box-shadow:var(--shadow-pop);
  min-width:200px;padding:5px;z-index:60;
}
.sw-dropdown-head{padding:8px 9px 9px;border-bottom:1px solid var(--hairline);margin-bottom:4px;display:flex;flex-direction:column;gap:2px}
.sw-dropdown-head .name{font-family:var(--display);font-size:13.5px;color:var(--ink-2)}
.sw-dropdown-head .email{font-size:11px;color:var(--soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sw-dropdown-item{
  display:block;width:100%;text-align:left;padding:8px 9px;border-radius:6px;font-size:12.5px;
  color:var(--ink-2);background:transparent;border:none;cursor:pointer;font-family:inherit;
}
.sw-dropdown-item:hover{background:#EFEBDF}
.sw-dropdown-item.destructive{color:var(--danger)}
.sw-dropdown-divider{border-top:1px solid #E6E2D2;margin:4px 0}

/* ---------- modal popups ---------- */
dialog.sw-modal{
  border:none;border-radius:var(--r-lg);padding:0;background:var(--chrome);
  box-shadow:var(--shadow-pop);width:min(460px, calc(100vw - 40px));
  color:var(--ink);margin:auto;
}
dialog.sw-modal.sw-modal-wide{width:min(680px, calc(100vw - 40px))}
dialog.sw-modal::backdrop{background:#1B231F99;animation:swfade 180ms var(--ease-out)}
@keyframes swmodalin{from{opacity:0;transform:translateY(12px) scale(.985)}to{opacity:1;transform:none}}
dialog.sw-modal[open]{animation:swmodalin 220ms var(--ease-out)}
.sw-modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 20px 14px;border-bottom:1px solid var(--hairline)}
.sw-modal-title{font-family:var(--display);font-size:18px}
.sw-modal-sub{font-size:12px;color:var(--soft);margin-top:2px;display:block}
.sw-modal-close{background:transparent;border:none;font-size:18px;line-height:1;color:var(--soft);cursor:pointer;padding:4px 6px;border-radius:6px}
.sw-modal-close:hover{background:#EBE7DA;color:var(--ink)}
.sw-modal-body{padding:18px 20px;display:flex;flex-direction:column;gap:13px;max-height:70vh;overflow-y:auto}
.sw-modal-foot{display:flex;gap:8px;justify-content:flex-end;padding:14px 20px;border-top:1px solid var(--hairline);background:#EDEBE1;border-radius:0 0 var(--r-lg) var(--r-lg)}
.sw-field-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.sw-field-check{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--muted)}
.sw-fab{
  width:38px;height:38px;border-radius:50%;background:var(--accent);color:var(--chrome);
  border:none;font-size:19px;line-height:1;display:grid;place-items:center;cursor:pointer;flex:none;
}
.sw-fab:hover{background:var(--accent-ink)}

/* utility */
.flex{display:flex}.flex-col{display:flex;flex-direction:column}.items-center{align-items:center}
.gap-6{gap:6px}.gap-8{gap:8px}.gap-10{gap:10px}.gap-14{gap:14px}
.mono{font-family:var(--mono)}
.hidden{display:none !important}

/* ---------- print / export ----------
   The old "Export" button just called window.print() on the live, panned/zoomed,
   chrome-full app view — printing the tool docks, guest list, inspector, and
   whatever fraction of the canvas happened to be scrolled into view, at whatever
   zoom the planner last left it at. This makes it print something a planner would
   actually want: the full floor plan at its natural scale (browser "fit to page"
   handles the final scaling), plus a plain table-by-table guest roster. */
@media print{
  @page{size:landscape;margin:12mm}
  body{background:#fff !important}
  .sw-noprint, .sw-header, dialog, .sw-dropdown{display:none !important}

  .sw-app{height:auto !important;display:block !important}
  .sw-body{display:block !important;height:auto !important}
  .sw-stage-wrap{overflow:visible !important;height:auto !important;background:#fff !important;position:static !important}
  .sw-world{position:static !important;transform:none !important;will-change:auto !important}
  .sw-sheet{box-shadow:none !important;background-image:none !important;margin:0 auto}

  .sw-print-header{display:flex !important;flex-direction:column;gap:2px;padding:0 0 12px}
  .sw-print-header .name{font-family:var(--display);font-size:20px;color:#000}
  .sw-print-header .meta{font-size:11px;color:#444;text-transform:uppercase;letter-spacing:.05em}

  .sw-print-roster{display:block !important;page-break-before:always;padding-top:12px}
  .sw-print-table{break-inside:avoid;margin-bottom:16px}
  .sw-print-table-name{font-family:var(--display);font-size:14px;display:block;margin-bottom:4px;border-bottom:1px solid #000;padding-bottom:3px;color:#000}
  .sw-print-roster table{width:100%;border-collapse:collapse;font-size:11px;color:#000}
  .sw-print-roster th{text-align:left;border-bottom:1px solid #999;padding:3px 6px}
  .sw-print-roster td{padding:3px 6px;border-bottom:1px solid #eee}
}

/* ---------- motion system ----------
   Rules this follows deliberately: 150–300ms for micro-interactions, transform
   and opacity only (compositor-thread, never layout), ease-out on enter and
   ease-in on exit, and at most one orchestrated moment per view. Everything
   here is off by default under prefers-reduced-motion (see the block at the
   end of this section). */
:root{
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --ease-in:cubic-bezier(.55,.06,.68,.19);
  --ease-spring:cubic-bezier(.34,1.4,.64,1);
  --t-fast:140ms; --t:200ms; --t-slow:320ms;
}

/* interactive affordances — every clickable thing gets a cursor and a
   sub-2px displacement on hover so it reads as feedback, not movement */
.btn,.sw-tool-btn,.sw-chip,.sw-guest-row,.sw-dropdown-item,.sw-modal-close,
.sw-panel-collapse-btn,.sw-edge-tab,.sw-view-dock button,.sw-menu .item{
  cursor:pointer;
  transition:background-color var(--t) var(--ease-out),
             border-color var(--t) var(--ease-out),
             color var(--t) var(--ease-out),
             transform var(--t-fast) var(--ease-out),
             box-shadow var(--t) var(--ease-out);
}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0);transition-duration:60ms}
.btn-primary:hover{box-shadow:0 6px 16px -6px #a97c2f9e}

/* visible keyboard focus everywhere — never removed, only restyled */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.btn:focus-visible,.sw-input:focus-visible,input:focus-visible,
select:focus-visible,textarea:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* card lift — used on dashboard event cards and marketing panels */
.sw-lift{transition:transform var(--t) var(--ease-out),box-shadow var(--t) var(--ease-out)}
.sw-lift:hover{transform:translateY(-3px);box-shadow:0 18px 34px -20px #1b231f7a}

/* entrance choreography: one orchestrated sequence per page load, staggered
   via --i on each child. Small y offset (10px) so it reads as a fade, not a slide. */
@keyframes swrise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.sw-enter{animation:swrise 460ms var(--ease-out) both;animation-delay:calc(var(--i,0) * 70ms)}

/* the cards are dealt onto the table on load. The wrapper animates (translate
   + fade) while the card inside keeps its own static rotation — composing the
   two on one element would mean re-declaring each card's angle in keyframes. */
@keyframes swcarddeal{from{opacity:0;transform:translateY(30px) scale(.94)}to{opacity:1;transform:none}}
.sw-deal{animation:swcarddeal 620ms var(--ease-spring) both;animation-delay:calc(var(--i,0) * 110ms)}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  .btn:hover,.sw-lift:hover{transform:none}
}

/* ---------- escort card (signature motif) ----------
   What Seatwise actually produces, physically, is a small card someone finds
   at the door with their name and table on it. This component — a tag shape
   with a punched hole, as if it hangs from a string — is that object, reused
   everywhere the product answers "where do I sit": the marketing hero, the
   RSVP confirmation, and (smaller) each table's label on the floor plan. */
.sw-tag{
  position:relative;display:inline-flex;align-items:center;gap:9px;
  background:var(--chrome);border:1px solid var(--panel-line);
  border-radius:3px 11px 11px 3px;box-shadow:var(--shadow-panel);
}
.sw-tag::before{
  content:"";position:absolute;left:9px;top:50%;transform:translateY(-50%);
  width:6px;height:6px;border-radius:50%;background:var(--desk);
  box-shadow:inset 0 1px 2px #1b231f40,0 0 0 1px var(--panel-line);
}

.sw-escort-card{
  position:relative;width:264px;background:var(--chrome);
  border-radius:4px 18px 18px 4px;padding:30px 28px 26px 34px;
  box-shadow:0 34px 60px -22px #1b231f59,0 12px 22px -10px #1b231f3d;
}
.sw-escort-card::before{
  content:"";position:absolute;left:15px;top:32px;width:11px;height:11px;border-radius:50%;
  background:var(--desk);box-shadow:inset 0 1px 3px #1b231f4d,0 0 0 1px var(--panel-line);
}
.sw-escort-card .eyebrow{display:block;margin-bottom:10px}
.sw-escort-card .guest-name{font-family:var(--display);font-size:26px;line-height:1.15;color:var(--ink);display:block}
.sw-escort-card .rule{height:1px;background:var(--hairline);margin:16px 0}
.sw-escort-card .table-row{display:flex;align-items:baseline;justify-content:space-between}
.sw-escort-card .table-row .lbl{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--soft)}
.sw-escort-card .table-row .val{font-family:var(--mono);font-size:15px;color:var(--accent-ink)}
/* Three layers on purpose, because transform is a single property and these
   three things must not overwrite each other:
     .card-slot   — absolute positioning + the deal-in animation (transform)
     .sw-escort-card — the static per-card rotation (transform)
     content      — untransformed, so text never inherits a skew
   Collapsing slot and card into one element makes the entrance animation
   clobber each card's angle mid-flight. */
.sw-escort-card-stack{position:relative;width:264px;height:300px}
.sw-escort-card-stack .card-slot{position:absolute;inset:0}
.sw-escort-card-stack .card-slot .sw-escort-card{
  transition:transform var(--t-slow) var(--ease-out),box-shadow var(--t-slow) var(--ease-out);
}
.sw-escort-card-stack .card-back{z-index:1}
.sw-escort-card-stack .card-back .sw-escort-card{transform:rotate(7deg) translate(18px,10px);opacity:.5}
.sw-escort-card-stack .card-mid{z-index:2}
.sw-escort-card-stack .card-mid .sw-escort-card{transform:rotate(-4deg) translate(-6px,4px);opacity:.78}
.sw-escort-card-stack .card-front{z-index:3}
.sw-escort-card-stack .card-front .sw-escort-card{transform:rotate(2deg)}
/* the top card lifts when you point at the stack — the single hover moment on
   this page, and it reinforces that these are physical objects on a table */
.sw-escort-card-stack:hover .card-front .sw-escort-card{
  transform:rotate(2deg) translateY(-8px);
  box-shadow:0 44px 70px -22px #1b231f66,0 14px 26px -10px #1b231f45;
}
.sw-escort-card-stack:hover .card-back .sw-escort-card{transform:rotate(9deg) translate(24px,12px)}
.sw-escort-card-stack:hover .card-mid .sw-escort-card{transform:rotate(-6deg) translate(-12px,6px)}

/* ---------- marketing responsive ----------
   The marketing page's grids were all fixed column counts with no breakpoints,
   so every one of them overflowed below ~900px. These collapse in the order
   the content actually reads. */
.sw-grid-4{display:grid;grid-template-columns:repeat(4,1fr)}
.sw-grid-2{display:grid;grid-template-columns:1fr 1fr}
@media (max-width: 1040px){
  .sw-hero{grid-template-columns:1fr !important;gap:36px !important}
  .sw-hero .sw-escort-card-stack{margin:0 auto}
  .sw-grid-4{grid-template-columns:1fr 1fr}
}
@media (max-width: 720px){
  .sw-grid-4,.sw-grid-2{grid-template-columns:1fr}
  .sw-nav{flex-wrap:wrap;gap:12px;padding:14px 18px}
  .sw-nav a.navlink{font-size:12.5px}
}

/* ================= RSVP guest-facing UI =================
   This is the only surface most people ever see, and it was the weakest:
   native selects, a multi-select listbox nobody knows how to operate, and
   radio cards whose "selected" styling was baked into the server-rendered
   style attribute — so it never moved when you picked the other option.
   Everything below is driven by :has()/:checked so state is always real. */

.sw-rsvp-shell{min-height:100vh;background:var(--paper);display:flex;flex-direction:column;align-items:center;padding:0 20px 60px}
.sw-rsvp-card{
  width:min(560px,100%);background:var(--chrome);border:1px solid var(--panel-line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-panel);overflow:hidden;
}
.sw-rsvp-banner{width:100%;height:190px;object-fit:cover;display:block}
.sw-rsvp-head{padding:24px 28px 18px;border-bottom:1px solid var(--hairline);background:var(--field)}
.sw-rsvp-eventname{font-family:var(--display);font-size:21px;line-height:1.2;display:block}
.sw-rsvp-meta{font-size:12px;color:var(--soft);margin-top:3px;display:block}
.sw-rsvp-blurb{font-size:13.5px;color:var(--body);line-height:1.6;margin-top:12px;white-space:pre-line}
.sw-rsvp-body{padding:26px 28px 24px;display:flex;flex-direction:column;gap:24px}
.sw-rsvp-foot{
  padding:18px 28px;border-top:1px solid var(--hairline);background:var(--field);
  display:flex;gap:10px;align-items:center;
}

/* step rail — shows position without pretending to be a progress bar */
.sw-rsvp-steps{display:flex;align-items:center;gap:8px;margin-top:14px}
.sw-rsvp-steps .seg{flex:1;height:3px;border-radius:2px;background:var(--panel-line)}
.sw-rsvp-steps .seg.on{background:var(--accent)}
.sw-rsvp-steps .lbl{font-family:var(--mono);font-size:10.5px;color:var(--soft);letter-spacing:.04em}

.sw-q{display:flex;flex-direction:column;gap:10px}
.sw-q-title{font-family:var(--display);font-size:19px;line-height:1.25}
.sw-q-help{font-size:12.5px;color:var(--muted);line-height:1.55}

/* ---- choice cards (yes / no) ----
   :has() means the card reacts to its own radio, so BOTH options highlight
   correctly. Previously the "selected" look was hardcoded onto the first card
   server-side and never moved when you chose the second one. */
.sw-choice{
  display:flex;align-items:center;gap:12px;border:1.5px solid var(--field-line);
  background:var(--chrome);border-radius:10px;padding:14px 15px;cursor:pointer;
  transition:border-color var(--t) var(--ease-out),background-color var(--t) var(--ease-out);
}
.sw-choice:hover{border-color:var(--accent-line);background:var(--field)}
.sw-choice input{accent-color:var(--accent);width:17px;height:17px;flex:none;cursor:pointer}
.sw-choice .t{font-size:14px;color:var(--ink)}
.sw-choice .s{font-size:12px;color:var(--soft);display:block;margin-top:2px}
.sw-choice:has(input:checked){border-color:var(--accent);background:var(--accent-wash);box-shadow:0 0 0 3px #a97c2f1f}
.sw-choice:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}

/* ---- selectable bubbles (interests) ---- */
.sw-bubbles{display:flex;flex-wrap:wrap;gap:8px}
.sw-bubble{
  position:relative;display:inline-flex;align-items:center;gap:6px;
  border:1.5px solid var(--field-line);background:var(--chrome);color:var(--ink-2);
  border-radius:var(--r-pill);padding:9px 15px;font-size:13px;cursor:pointer;
  transition:border-color var(--t) var(--ease-out),background-color var(--t) var(--ease-out),
             color var(--t) var(--ease-out),transform var(--t-fast) var(--ease-out);
  min-height:38px;
}
.sw-bubble input{position:absolute;opacity:0;width:100%;height:100%;left:0;top:0;margin:0;cursor:pointer}
.sw-bubble:hover:not(.disabled){border-color:var(--accent-line);transform:translateY(-1px)}
.sw-bubble.selected{background:var(--accent);border-color:var(--accent);color:var(--chrome)}
.sw-bubble.selected::before{content:"✓";font-size:11px}
.sw-bubble.disabled{opacity:.4;cursor:not-allowed}
.sw-bubble:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}

/* ---- searchable multi-select picker ---- */
.sw-picker{border:1px solid var(--field-line);border-radius:10px;background:var(--chrome);overflow:hidden}
.sw-picker-chips{display:flex;flex-wrap:wrap;gap:6px;padding:10px 10px 0}
.sw-picker-chip{
  display:inline-flex;align-items:center;gap:7px;background:var(--accent-wash);
  border:1px solid var(--accent-line);color:var(--accent-ink);border-radius:var(--r-pill);
  padding:5px 10px;font-size:12px;cursor:pointer;font-family:inherit;
}
.sw-picker-chip:hover{background:var(--accent);color:var(--chrome);border-color:var(--accent)}
.sw-picker-search{
  width:100%;border:none;border-bottom:1px solid var(--hairline);padding:12px 14px;
  font-size:13.5px;outline:none;background:transparent;color:var(--ink);
}
.sw-picker-search:focus{border-bottom-color:var(--accent)}
.sw-picker-list{max-height:210px;overflow-y:auto;overscroll-behavior:contain}
.sw-picker-row{
  display:flex;align-items:center;gap:11px;padding:10px 14px;cursor:pointer;
  border-bottom:1px solid var(--row-line);font-size:13.5px;color:var(--ink-2);
  transition:background-color var(--t-fast) var(--ease-out);min-height:44px;
}
.sw-picker-row:last-child{border-bottom:none}
.sw-picker-row:hover:not(.disabled){background:var(--field)}
.sw-picker-row input{accent-color:var(--accent);width:16px;height:16px;flex:none;cursor:pointer}
.sw-picker-row.selected{background:var(--accent-wash);color:var(--accent-ink)}
.sw-picker-row.disabled{opacity:.42;cursor:not-allowed}
.sw-picker-empty{padding:16px 14px;font-size:12.5px;color:var(--soft);text-align:center}
.sw-picker-count{font-family:var(--mono);font-size:11px;color:var(--soft)}
.sw-q-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}

@media (max-width:560px){
  .sw-rsvp-body,.sw-rsvp-head,.sw-rsvp-foot{padding-left:18px;padding-right:18px}
  .sw-rsvp-card{border-radius:0;border-left:none;border-right:none}
  .sw-rsvp-shell{padding-left:0;padding-right:0}
}

/* ---------- footer ---------- */
.sw-footer{border-top:1px solid var(--hairline);margin-top:20px}
.sw-footer-top{
  display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:34px;padding:38px 0 30px;
}
.sw-footer-h{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--soft)}
.sw-footer a{font-size:13px;color:var(--body)}
.sw-footer a:hover{color:var(--accent-ink)}
.sw-social{display:inline-flex;align-items:center;gap:7px}
.sw-footer-bottom{
  border-top:1px solid var(--hairline);padding:18px 0 44px;display:flex;
  justify-content:space-between;font-size:12px;color:var(--soft);gap:12px;flex-wrap:wrap;
}
@media (max-width:720px){
  .sw-footer-top{grid-template-columns:1fr 1fr;gap:26px}
}

/* ---------- legal pages ---------- */
.sw-legal{font-size:14.5px;line-height:1.75;color:var(--body)}
.sw-legal h2{
  font-family:var(--display);font-size:19px;font-weight:500;color:var(--ink);
  margin:34px 0 10px;letter-spacing:-.005em;
}
.sw-legal p{margin:0 0 14px}
.sw-legal ul{margin:0 0 16px;padding-left:20px}
.sw-legal li{margin-bottom:7px}
.sw-legal em{color:var(--muted)}
.sw-legal > p:first-child{
  background:var(--field);border-left:3px solid var(--accent);border-radius:0 8px 8px 0;
  padding:14px 18px;margin-bottom:26px;font-style:normal;
}
.sw-legal > p:first-child em{font-style:normal;color:var(--ink-2)}

/* ---------- RSVP privacy note ---------- */
.sw-privacy-note{
  display:flex;gap:10px;align-items:flex-start;max-width:min(560px,100%);
  margin-top:16px;padding:13px 16px;background:var(--ok-wash);
  border:1px solid #D6DFD3;border-radius:10px;
  font-size:12.5px;line-height:1.55;color:var(--ok);
}
.sw-privacy-note svg{flex:none;margin-top:1px}

/* brief highlight so clicking the header conflict pill is always acknowledged,
   even when the panel was already showing the same content */
@keyframes swflash{
  0%{background:transparent}
  18%{background:var(--accent-wash)}
  100%{background:transparent}
}
.sw-flash{animation:swflash 1.1s var(--ease-out);border-radius:8px}
@media (prefers-reduced-motion: reduce){ .sw-flash{animation:none} }

/* contextual notice inside the RSVP form (e.g. "your partner already replied") */
.sw-notice{
  display:flex;gap:11px;align-items:flex-start;padding:14px 16px;
  background:var(--accent-wash);border:1px solid var(--accent-line);
  border-radius:10px;font-size:13px;line-height:1.6;color:var(--ink-2);
}
.sw-notice svg{flex:none;margin-top:2px;color:var(--accent-ink)}
.sw-notice strong{font-weight:600}

/* ---------- "sound familiar?" problem statement ----------
   A full-bleed dark band: the one moment on the page that isn't paper-coloured,
   so the problem lands before the product is offered as the answer. */
.sw-pain{
  background:var(--ink);color:var(--paper);border-radius:var(--r-lg);
  margin:8px 0 4px;overflow:hidden;position:relative;
}
.sw-pain::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(circle at center, #FBFAF412 1.3px, transparent 1.3px);
  background-size:34px 34px;
}
.sw-pain-inner{padding:46px 48px;max-width:64ch;position:relative;z-index:1}
.sw-pain .eyebrow{color:var(--accent-line)}
.sw-pain-h{
  font-family:var(--display);font-size:clamp(23px,3.1vw,32px);font-weight:500;
  line-height:1.22;letter-spacing:-.015em;margin:12px 0 14px;color:var(--paper);
}
.sw-pain-p{font-size:14.5px;line-height:1.7;color:#C9CCC2;margin:0}
@media (max-width:720px){ .sw-pain-inner{padding:32px 24px} }

/* ---------- contact ---------- */
.sw-contact{
  border-top:1px solid var(--hairline);padding:54px 0 12px;
  display:flex;flex-direction:column;align-items:flex-start;gap:0;
}
.sw-contact-h{font-family:var(--display);font-size:clamp(24px,3vw,30px);font-weight:500;margin:8px 0 10px}
.sw-contact-p{font-size:14.5px;line-height:1.65;color:var(--body);margin:0 0 22px;max-width:52ch}
.sw-contact-mail{
  font-family:var(--display);font-size:clamp(22px,3.4vw,30px);color:var(--accent-ink);
  border-bottom:2px solid var(--accent-line);padding-bottom:3px;letter-spacing:-.01em;
  transition:border-color var(--t) var(--ease-out),color var(--t) var(--ease-out);
}
.sw-contact-mail:hover{color:var(--accent);border-bottom-color:var(--accent)}
.sw-contact-small{font-size:12.5px;color:var(--soft);margin:20px 0 0}

/* ---------- floor-plan walkthrough ---------- */
.sw-tour[hidden]{display:none}
.sw-tour{position:fixed;inset:0;z-index:200}
body.sw-tour-open{overflow:hidden}

/* Swallows every click while the tour is open, so nothing underneath can be
   operated half-way through a step. Transparent by default: the spotlight's
   box-shadow already dims everything outside itself, and dimming here as well
   would darken the one element the step is trying to point at. */
.sw-tour-scrim{position:absolute;inset:0;cursor:default;background:transparent}
/* A centred step has no spotlight, so the scrim has to do the dimming instead. */
.sw-tour.is-centered .sw-tour-scrim{background:rgba(20,24,21,.62)}

/* The lit ring. Its box-shadow is what dims the rest of the page — one element
   doing both jobs, so the hole can never drift out of register with the dimming. */
.sw-tour-spot{
  position:fixed;border-radius:var(--r-lg);pointer-events:none;
  box-shadow:0 0 0 9999px rgba(20,24,21,.62);
  border:1.5px solid var(--accent);
  transition:left var(--t-med) var(--ease-out),top var(--t-med) var(--ease-out),
             width var(--t-med) var(--ease-out),height var(--t-med) var(--ease-out);
}
.sw-tour-spot{z-index:1}

.sw-tour-card{
  position:fixed;z-index:2;width:min(370px, calc(100vw - 24px));
  background:var(--chrome);border:1px solid var(--panel-line);
  border-radius:var(--r-lg);box-shadow:var(--shadow-pop);
  padding:18px 20px 16px;outline:none;
  animation:swfade var(--t-med) var(--ease-out) both;
}
.sw-tour-progress{display:flex;gap:4px;margin-bottom:12px}
.sw-tour-progress span{
  height:3px;flex:1;border-radius:2px;background:var(--hairline);
  transition:background var(--t-fast) var(--ease-out);
}
.sw-tour-progress span.done{background:var(--accent)}
.sw-tour-step{
  display:block;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--soft);
}
.sw-tour-title{
  font-family:var(--display);font-size:19px;font-weight:600;line-height:1.25;
  color:var(--ink);margin:5px 0 0;
}
.sw-tour-body{
  font-size:13px;line-height:1.6;color:var(--ink-2);margin:9px 0 0;
}
.sw-tour-actions{
  display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:16px;
}
.sw-tour-nav{display:flex;gap:8px}
.sw-tour-skip{font-size:12.5px;color:var(--soft)}
.sw-tour-card .btn:disabled{opacity:.4;cursor:not-allowed}
.sw-tour-hint{
  display:block;margin-top:12px;padding-top:10px;border-top:1px solid var(--hairline);
  font-size:11px;line-height:1.5;color:var(--soft);
}
.sw-tour-hint b{color:var(--body);font-weight:600}

/* The replay button living in the canvas view dock. */
.sw-view-dock button.sw-tour-btn{font-weight:600}

@media (prefers-reduced-motion: reduce){
  .sw-tour-spot{transition:none}
  .sw-tour-card{animation:none}
}

/* ---------- paywall ---------- */
.sw-tabs a.is-locked{color:var(--soft)}
.sw-tabs a.is-locked .tab-lock{margin-left:5px;vertical-align:-1px;opacity:.75}
.sw-tabs a.is-locked:hover{color:var(--accent)}

.sw-upgrade-bar{
  flex:none;display:flex;align-items:center;gap:12px;padding:9px 16px;
  background:var(--accent-wash);border-bottom:1px solid var(--accent-line);
  font-size:12.5px;line-height:1.5;color:var(--ink-2);
}
.sw-upgrade-dot{
  flex:none;width:7px;height:7px;border-radius:50%;background:var(--accent);
}
.sw-upgrade-text{flex:1;min-width:0}
.sw-upgrade-text strong{color:var(--ink)}
.sw-upgrade-btn{flex:none;padding:7px 14px;font-size:12.5px}

.sw-unlock{
  max-width:1100px;margin:0 auto;padding:38px 20px 80px;
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:40px;align-items:start;
}
.sw-unlock-title{
  font-family:var(--display);font-size:32px;font-weight:600;line-height:1.2;
  color:var(--ink);margin:8px 0 0;max-width:20ch;
}
.sw-unlock-lede{font-size:14px;line-height:1.65;color:var(--ink-2);margin:12px 0 0;max-width:56ch}
.sw-unlock-lede strong{color:var(--ink)}

.sw-unlock-progress{
  margin-top:26px;padding:18px 20px;background:var(--chrome);
  border:1px solid var(--panel-line);border-radius:var(--r-lg);
}
.sw-unlock-stats{display:flex;gap:28px;margin-top:12px;flex-wrap:wrap}
.sw-unlock-stat{display:flex;flex-direction:column;gap:2px;opacity:.4}
.sw-unlock-stat.is-done{opacity:1}
.sw-unlock-stat .n{font-size:26px;font-weight:500;color:var(--accent-ink);line-height:1}
.sw-unlock-stat .l{font-size:11.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--soft)}
.sw-unlock-note{display:block;margin-top:12px;font-size:11.5px;color:var(--soft);line-height:1.55}

.sw-unlock-gets{margin-top:26px}
.sw-unlock-gets ul,.sw-unlock-free ul{list-style:none;margin:12px 0 0;padding:0}
.sw-unlock-gets li{
  position:relative;padding:0 0 0 22px;margin-bottom:13px;
  font-size:13px;line-height:1.6;color:var(--ink-2);
}
.sw-unlock-gets li::before{
  content:"";position:absolute;left:2px;top:8px;width:7px;height:7px;
  border-radius:50%;background:var(--accent);
}
.sw-unlock-gets li strong{color:var(--ink)}

.sw-unlock-cta{margin-top:28px}
.sw-unlock-cta .btn{padding:14px 26px;font-size:14.5px}
.sw-unlock-terms{
  display:block;margin-top:12px;font-size:11.5px;line-height:1.6;color:var(--soft);max-width:52ch;
}
.sw-unlock-back{margin-top:22px;display:flex;gap:10px;font-size:12.5px;color:var(--soft)}
.sw-unlock-back a{color:var(--accent-ink);text-decoration:underline}

.sw-unlock-aside{display:flex;flex-direction:column;gap:20px}
.sw-unlock-preview{
  position:relative;border:1px solid var(--panel-line);border-radius:var(--r-lg);
  overflow:hidden;background:var(--chrome);
}
/* direct child only — the lock badge nested inside must keep its own 18px size */
.sw-unlock-preview > svg{display:block;width:100%;height:auto;opacity:.5;filter:saturate(.75)}
.sw-unlock-lock{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:8px;
  flex-direction:column;color:var(--ink);font-size:12px;letter-spacing:.05em;
  text-transform:uppercase;background:linear-gradient(180deg,#EDEBE100,#EDEBE1cc);
}
.sw-unlock-free{
  padding:18px 20px;background:var(--chrome);
  border:1px solid var(--panel-line);border-radius:var(--r-lg);
}
.sw-unlock-free li{
  position:relative;padding-left:18px;margin-bottom:8px;font-size:12.5px;
  line-height:1.55;color:var(--ink-2);
}
.sw-unlock-free li::before{
  content:"";position:absolute;left:2px;top:7px;width:5px;height:5px;
  border-radius:50%;background:var(--ok);
}

@media (max-width: 880px){
  .sw-unlock{grid-template-columns:1fr;gap:26px}
  .sw-unlock-title{font-size:26px}
  .sw-upgrade-bar{flex-wrap:wrap}
  .sw-upgrade-text{flex:1 1 100%;order:2}
}

/* ---------- billing confirmation banner ---------- */
.sw-billing-status{
  display:flex;align-items:flex-start;gap:10px;margin-top:12px;
  padding:12px 14px;border-radius:var(--r-md);
  border:1px solid var(--hairline);background:var(--chrome);
  font-size:12.5px;line-height:1.55;color:var(--ink-2);
}
.sw-billing-status .dot{
  flex:none;width:8px;height:8px;border-radius:50%;
  background:var(--accent);margin-top:6px;
}
.sw-billing-status.is-paid{border-color:var(--ok);background:var(--ok-wash)}
.sw-billing-status.is-paid .dot{background:var(--ok)}
.sw-billing-status.is-stalled{border-color:var(--accent-line);background:var(--accent-wash)}
.sw-billing-status a{color:var(--accent-ink);text-decoration:underline}

.sw-spinner{
  flex:none;width:13px;height:13px;margin-top:3px;border-radius:50%;
  border:2px solid var(--accent-line);border-top-color:var(--accent);
  animation:swspin .7s linear infinite;
}
@keyframes swspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce){
  .sw-spinner{animation-duration:2.4s}
}

/* ---------- danger zone (event settings) ---------- */
.sw-danger-zone{
  border:1px solid var(--danger-line);background:var(--danger-wash);
  border-radius:var(--r-lg);padding:20px;margin-top:12px;
}
.sw-danger-zone strong{color:var(--ink)}

/* ---------- band picker (paywall) ---------- */
.sw-unlock-bands{margin-top:26px}
.sw-band-picker{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
@media (max-width:640px){ .sw-band-picker{grid-template-columns:repeat(2,1fr)} }
.sw-band-opt{
  position:relative;display:flex;flex-direction:column;gap:2px;cursor:pointer;
  padding:13px 14px;border:1px solid var(--hairline);border-radius:var(--r-md);
  background:var(--chrome);transition:border-color var(--t-fast) var(--ease-out),
  background var(--t-fast) var(--ease-out);
}
.sw-band-opt input{position:absolute;opacity:0;pointer-events:none}
.sw-band-opt:hover{border-color:var(--accent-line)}
.sw-band-opt:has(input:checked){border-color:var(--accent);background:var(--accent-wash);
  box-shadow:0 0 0 1px var(--accent)}
.sw-band-opt:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
.sw-band-opt .seats{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;color:var(--soft)}
.sw-band-opt .price{font-family:var(--display);font-size:22px;line-height:1.1;color:var(--ink)}
.sw-band-opt .tier{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--accent)}
.sw-band-opt .why{font-size:10.5px;color:var(--danger);line-height:1.35;margin-top:3px}
/* A band smaller than the list is not a choice, so it is shown and disabled rather
   than hidden — seeing why it is unavailable beats wondering where it went. */
.sw-band-opt.is-too-small{opacity:.5;cursor:not-allowed;background:var(--desk)}
.sw-band-opt.is-too-small:hover{border-color:var(--hairline)}

/* ---------- Paddle checkout hand-off page ---------- */
.sw-checkout{min-height:100vh;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:26px;background:var(--desk);padding:24px}
.sw-checkout-card{
  background:var(--chrome);border:1px solid var(--panel-line);border-radius:var(--r-lg);
  padding:28px 32px;max-width:420px;text-align:center;display:flex;flex-direction:column;
  align-items:center;gap:12px;box-shadow:var(--shadow-panel);
}
.sw-checkout-card p{margin:0;font-size:14px;color:var(--ink-2);line-height:1.55}
.sw-checkout-note{font-size:12px;color:var(--soft);line-height:1.55}
.sw-checkout-note a{color:var(--accent-ink);text-decoration:underline}
