/* V3 Studio — shared styles for plan, build, and publish screens. */

:root {
    --ink-900: #0b0f19;
    --ink-700: #1f2937;
    --ink-500: #4b5563;
    --ink-300: #9ca3af;
    --ink-100: #e5e7eb;
    --canvas: #fafafa;
    --surface: #ffffff;
    --accent: #4F46E5;
    --accent-soft: #eef2ff;
    --warn: #f59e0b;
    --danger: #dc2626;
    --success: #16a34a;
    --radius-lg: 16px;
    --radius-md: 12px;
    --radius-sm: 8px;
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
    --shadow-md: 0 4px 18px rgba(15, 23, 42, 0.08);
}

* { box-sizing: border-box; }

body.studio-body {
    margin: 0;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--canvas);
    color: var(--ink-900);
    min-height: 100vh;
}
/* Build + plan screens run a fixed-viewport layout so each pane owns its
   own scrollbar instead of the whole page scrolling as one. Nav is fixed
   height (flex-shrink:0), main region takes remaining viewport. */
body.studio-body.no-page-scroll {
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
body.studio-body.no-page-scroll > .studio-nav,
body.studio-body.no-page-scroll > .plan-nav { flex-shrink: 0; position: static; }
/* Step-2 (Preview) footer — Back / Save & Proceed buttons. Sticks
   to the viewport bottom inside the flex column; the build-layout
   above it claims the remaining space via flex: 1 1 auto. */
body.studio-body.no-page-scroll > .build-footer { flex-shrink: 0; }
body.studio-body.no-page-scroll > .build-layout,
body.studio-body.no-page-scroll > .plan-layout {
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
}

a { color: var(--accent); text-decoration: none; }

.studio-nav {
    position: sticky;
    top: 0;
    /* Sits above the floating /plan TOC (z=40) so the avatar dropdown's
       bottom half (Your events / Profile / Org / Event hub / Sign out)
       isn't clipped by the TOC card on long viewports. The dropdown's
       inner z-index (70) is trapped in this nav's stacking context, so
       the nav itself has to outrank anything that floats over the
       content below — that means TOC, regen overlay (z=30), and other
       in-page floaters. Modals (z=9999) still cover the nav as expected. */
    z-index: 50;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--ink-100);
    padding: 0 22px;
    /* three-column grid keeps stepper true-centred regardless of left/right widths */
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 24px;
    /* Fixed height — shared across /events, /studio/*, and /admin/platform/*
       so the three shells line up. Children size down to fit (see the
       .studio-nav .btn-publish-cta override below). */
    height: 64px;
}
.studio-nav > .studio-brand { justify-self: start; }
/* Brand + event-switcher cluster on the left of /build. Wraps the
   logo and the manage-event-switcher so the current event sits
   immediately next to the logo instead of being stranded in the
   right-hand nav cluster. `min-width: 0` lets the switcher's name
   span ellipsis cleanly when the event name is long. */
.studio-nav > .studio-brand-group {
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}
.studio-nav > .studio-nav-right { justify-self: end; }
.studio-brand {
    display: inline-flex;
    align-items: center;
    height: 36px;  /* bumped from 28 so the wordmark reads at nav scale */
}
.studio-brand img {
    height: 36px;
    width: auto;
    display: block;
    /* New PNG is already black-wordmark + red-dot on transparent — no
       invert needed. The old filter was for the previous white-logo PNG. */
}
.studio-nav-steps {
    display: flex;
    gap: 22px;
    font-size: 13px;
    color: var(--ink-500);
    flex-wrap: nowrap;
    justify-self: center;
}
.studio-nav-steps .step {
    position: relative;
    padding-bottom: 4px;
    text-decoration: none;
    color: inherit;
}
/* Done steps render as <a> — full clickable revisits. Muted colour
   matches the old span; subtle hover lift makes the affordance
   obvious on hover. */
.studio-nav-steps .step.done {
    color: var(--ink-700);
    cursor: pointer;
    transition: color 0.12s, border-color 0.12s;
    border-bottom: 1px solid transparent;
}
.studio-nav-steps .step.done:hover {
    color: var(--ink-900);
    border-bottom-color: var(--ink-300, #d4d4d8);
}
.studio-nav-steps .step.current { color: var(--ink-900); font-weight: 600; }
/* Pending = forward step the user hasn't reached yet. Inert, so a
   click into an empty Registrations / blocked Publish doesn't feel
   like the UI broke — the title= tooltip explains the gate. */
.studio-nav-steps .step.is-pending {
    color: var(--ink-400, #9ca3af);
    cursor: not-allowed;
}
.studio-nav-steps .step.current::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -2px;
    height: 2px; border-radius: 2px;
    background: var(--accent);
}
.studio-nav-right { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-500); }

/* ── Studio top-nav help pill ───────────────────────────────────────────
   Sits next to the dark Publish button. Light fill so it reads as a
   companion (not competing for attention) and so the eye still goes
   to Publish first. Hover lifts subtly. */
.studio-help-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 12px;
    background: #fff;
    color: var(--ink-700, #374151);
    border: 1px solid var(--ink-100, #e5e7eb);
    border-radius: 999px;
    font-size: 13px; font-weight: 500;
    text-decoration: none;
    transition: background 120ms ease, border-color 120ms ease,
                color 120ms ease, transform 120ms ease,
                box-shadow 120ms ease;
}
.studio-help-pill:hover {
    background: #f9fafb;
    color: var(--ink-900, #0b0f19);
    border-color: #d1d5db;
    transform: translateY(-1px);
    box-shadow: 0 4px 10px -4px rgba(15, 23, 42, 0.12);
}
.studio-help-pill:focus-visible {
    outline: none;
    border-color: #a5b4fc;
    box-shadow: 0 0 0 3px rgba(165, 180, 252, 0.35);
}
.studio-help-pill svg { color: var(--ink-500, #6b7280); flex-shrink: 0; }
.studio-help-pill:hover svg { color: var(--ink-900, #0b0f19); }
@media (max-width: 640px) {
    /* On narrow viewports, drop the label and keep just the icon
       so the right rail doesn't crowd the Publish button. */
    .studio-help-pill { padding: 7px 9px; }
    .studio-help-pill > span { display: none; }
}

/* ── Leave-confirm modal ───────────────────────────────────────────────── */
/* Same z-index logic as .publish-disclosure-overlay — sticky nav creates
   a stacking context that out-ranks z=100, so the leave-confirm scrim
   was also letting the nav's Back/Publish buttons read as clickable.
   9999 matches the documented modal convention. */
.leave-confirm-overlay {
    /* Same defensive pattern as .publish-disclosure-overlay above.
       Locks the floating-overlay properties past any later cascade. */
    position: fixed !important;
    top: 0 !important; right: 0 !important;
    bottom: 0 !important; left: 0 !important;
    inset: 0 !important;
    z-index: 9999 !important;
    display: flex !important;
    align-items: center !important; justify-content: center !important;
    background: rgba(11, 15, 25, 0.55);
    backdrop-filter: blur(4px);
    padding: 24px;
    margin: 0;
    width: auto; height: auto;
    transform: none;
    animation: leave-fade-in 0.15s ease-out;
}
@keyframes leave-fade-in { from { opacity: 0; } to { opacity: 1; } }
.leave-confirm-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 28px 28px 22px;
    max-width: 420px;
    width: 100%;
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.25);
    animation: leave-pop-in 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes leave-pop-in {
    from { opacity: 0; transform: translateY(6px) scale(0.98); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}
.leave-confirm-card h3 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 26px;
    line-height: 1.15;
    letter-spacing: -0.02em;
    margin: 0 0 10px;
    color: var(--ink-900);
}
.leave-confirm-card p {
    font-size: 14px;
    color: var(--ink-500);
    line-height: 1.55;
    margin: 0 0 22px;
}
.leave-confirm-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}
.leave-confirm-actions .btn-primary { padding: 10px 18px; font-size: 13px; }
.leave-confirm-actions .btn-ghost { padding: 10px 16px; font-size: 13px; }

/* ── Events list ───────────────────────────────────────────────────────── */
.events-main { max-width: 980px; margin: 0 auto; padding: 40px 32px 80px; }
.events-hero { margin-bottom: 32px; }
.events-hero h1 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 44px;
    letter-spacing: -0.02em;
    margin: 0 0 6px;
    color: var(--ink-900);
}
.events-hero p { color: var(--ink-500); font-size: 14px; margin: 0; }

/* ── Events toolbar (sort + view toggle) ──────────────────────────
   Sits above the list. Right-aligned so the eye tracks Title → list
   first, and the controls feel secondary. Single-row on desktop,
   stacks on narrow viewports. */
.events-toolbar {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 12px; margin-bottom: 14px;
    flex-wrap: wrap;
}
.events-sort-label { display: inline-flex; align-items: center; gap: 8px; }
.events-sort-hint {
    font-size: 11px; font-weight: 600; letter-spacing: 0.5px;
    text-transform: uppercase; color: var(--ink-500);
}
.events-sort-select {
    appearance: none;
    background: #fff url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236b7280' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 10px center;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    padding: 6px 28px 6px 10px;
    font-size: 13px; color: var(--ink-900);
    cursor: pointer;
    transition: border-color 0.12s;
}
.events-sort-select:hover { border-color: #c7d2fe; }
.events-sort-select:focus { outline: none; border-color: var(--accent, #4f46e5); }
/* Segmented view toggle — two buttons that share a border ring and
   a single active-fill that slides between them. Simpler than a pair
   of separate pills, and a familiar shape for list/card switchers. */
.events-view-toggle {
    display: inline-flex;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    background: #fff;
    padding: 2px;
}
.events-view-btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 10px;
    font: inherit; font-size: 12.5px; font-weight: 500;
    color: var(--ink-500);
    background: transparent;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.events-view-btn:hover { color: var(--ink-900); }
.events-view-btn.is-active {
    background: var(--ink-900);
    color: #fff;
}
.events-view-btn svg { opacity: 0.9; }

/* ── Cards (default) — full-width rows with bigger type + stats ─────
   List view was dropped; cards IS the compact list-like view. The
   banner markup below each card's <a> stays hidden here (tile-only)
   so the card reads as a single row. */
.events-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.events-list.view-cards { gap: 12px; }
.events-list.view-cards .event-card-link { padding: 18px 22px; }
.events-list.view-cards .event-stat span {
    display: block; font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.08em;
}
/* Banner hidden in cards view — it's a tile-only affordance. */
.events-list.view-cards .event-card-banner { display: none; }

/* ── Tiles — grid of compact thumbnails, scan-friendly at scale ─────
   Every tile is a small card with title + meta + status. Stats live
   at the bottom as a one-line strip. 3 cols on desktop, 2 on tablet,
   1 on phone. The tile's <a> becomes flex-column so its footer sits
   at the bottom regardless of title length. */
.events-list.view-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 12px;
}
.events-list.view-tiles .event-card { display: flex; flex-direction: column; }
.events-list.view-tiles .event-card-link {
    display: flex; flex-direction: column;
    grid-template-columns: none;
    gap: 10px;
    padding: 14px 16px 12px;
    flex: 1;
}
.events-list.view-tiles .event-card-main h2 {
    font-size: 14.5px; margin: 0 0 6px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.events-list.view-tiles .event-card-meta {
    font-size: 11px; gap: 8px;
    color: var(--ink-500);
}
.events-list.view-tiles .event-card-meta .pill {
    display: none;  /* Format pill noisy at tile size — keep meta dense. */
}
.events-list.view-tiles .event-card-stats {
    margin-top: auto;
    gap: 14px;
    padding-top: 10px;
    border-top: 1px dashed var(--ink-100);
}
.events-list.view-tiles .event-stat strong { font-size: 13px; }
.events-list.view-tiles .event-stat span {
    display: block; font-size: 9.5px; text-transform: uppercase;
    letter-spacing: 0.06em;
}
.events-list.view-tiles .event-card-status { margin-top: -2px; }
.events-list.view-tiles .event-card-actions { padding: 0 16px 12px; }

/* Tile banner — the top strip of each card in tile mode. Image when
   the event has a hero; deterministic gradient keyed off event.id
   when it doesn't (no stock photos, no fabricated URLs — pure CSS).
   Letter initial floats over the pattern so each tile still reads
   as "this event" while scanning. */
.event-card-banner {
    position: relative;
    height: 120px;
    border-radius: 12px 12px 0 0;
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-color: #e5e7eb;
}
.events-list.view-tiles .event-card-banner { display: block; }
.events-list.view-tiles .event-card { overflow: hidden; }
/* Subtle inset shadow on the bottom edge so the banner visually
   separates from the content without a hard line. */
.event-card-banner::after {
    content: "";
    position: absolute; inset: 0;
    box-shadow: inset 0 -18px 24px -20px rgba(11, 15, 25, 0.18);
}
.event-card-banner-initial {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 56px;
    color: rgba(255, 255, 255, 0.92);
    line-height: 1;
    text-shadow: 0 2px 16px rgba(11, 15, 25, 0.35);
    z-index: 1;
}
/* Eight deterministic gradient variants — event.id % 8 picks one.
   Palette mixes warm / cool / neutral pairs so a grid of adjacent
   tiles reads as intentional variety rather than random noise. */
.event-card-banner.is-pattern[data-seed="0"] { background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%); }
.event-card-banner.is-pattern[data-seed="1"] { background: linear-gradient(135deg, #0ea5e9 0%, #06b6d4 100%); }
.event-card-banner.is-pattern[data-seed="2"] { background: linear-gradient(135deg, #10b981 0%, #14b8a6 100%); }
.event-card-banner.is-pattern[data-seed="3"] { background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%); }
.event-card-banner.is-pattern[data-seed="4"] { background: linear-gradient(135deg, #ec4899 0%, #f43f5e 100%); }
.event-card-banner.is-pattern[data-seed="5"] { background: linear-gradient(135deg, #6366f1 0%, #3b82f6 100%); }
.event-card-banner.is-pattern[data-seed="6"] { background: linear-gradient(135deg, #334155 0%, #0f172a 100%); }
.event-card-banner.is-pattern[data-seed="7"] { background: linear-gradient(135deg, #db2777 0%, #7c3aed 100%); }

.event-card {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.event-card:hover { border-color: #c7d2fe; box-shadow: 0 4px 18px rgba(15, 23, 42, 0.06); }

.event-card-link {
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 20px;
    align-items: center;
    padding: 18px 22px;
    text-decoration: none;
    color: inherit;
}
.event-card-main h2 {
    font-family: 'Inter', sans-serif;
    font-weight: 600;
    font-size: 16px;
    margin: 0 0 6px;
    color: var(--ink-900);
    letter-spacing: -0.01em;
}
.event-card-meta {
    display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
    font-size: 12px; color: var(--ink-500);
}
.event-card-meta span { display: inline-flex; align-items: center; gap: 4px; }

.event-card-stats { display: flex; gap: 22px; align-items: center; }
.event-stat { text-align: center; }
.event-stat strong {
    display: block; font-size: 16px; font-weight: 600;
    color: var(--ink-900); font-variant-numeric: tabular-nums;
}
.event-stat span {
    display: block; font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--ink-500);
}

.event-card-status { display: flex; align-items: center; }
.status-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 10px; border-radius: 999px;
    font-size: 12px; font-weight: 500;
}
.status-pill.status-live { background: #ecfdf5; color: #065f46; }
.status-pill.status-ended { background: #fef3c7; color: #92400e; }
.status-pill.status-draft { background: #f3f4f6; color: var(--ink-500); }
.status-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status-live .status-dot { background: #10b981; box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.22); }
.status-ended .status-dot { background: #d97706; }

.event-card-actions {
    padding: 0 22px 14px;
    display: flex; gap: 12px; align-items: center;
}

.events-empty {
    text-align: center;
    padding: 80px 32px;
    background: var(--surface);
    border: 1px dashed var(--ink-100);
    border-radius: 16px;
}
.events-empty-head {
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 32px; font-weight: 400;
    color: var(--ink-900);
    margin: 0 0 8px;
}
.events-empty-sub { color: var(--ink-500); font-size: 15px; margin: 0 0 24px; }

@media (max-width: 780px) {
    .event-card-link { grid-template-columns: 1fr; gap: 12px; }
    .event-card-stats { gap: 16px; }
}

/* ── Plan layout (chat left · summary right — each with own scroll) ────── */
.plan-layout {
    display: grid;
    /* 2 panes: chat · full-width questionnaire. Preview of the form
       lives on the /build step where builder + preview belong together.
       Plan is pure composition — one artifact at a time. Chat column
       width keyed off --plan-chat-w so the resizer can mutate it live,
       matching the /build screen's --chat-w pattern. */
    --plan-chat-w: 420px;
    --plan-chat-w-min: 280px;
    --plan-chat-w-max: 560px;
    grid-template-columns: var(--plan-chat-w) 1fr;
    height: calc(100vh - 56px);
    overflow: hidden;
    position: relative;  /* anchor for the .chat-resizer absolute element */
}
/* Chat-disabled variant — the /plan template now renders a static
   guidance panel in place of the chat (organisers were treating the
   chat as the primary input and ignoring the questionnaire). The
   guide column is a fixed-width sidebar without a draggable resizer,
   since there's nothing to resize anymore. */
.plan-layout.plan-layout-no-chat {
    --plan-chat-w: 360px;
    grid-template-columns: var(--plan-chat-w) 1fr;
}
@media (max-width: 900px) {
    .plan-layout.plan-layout-no-chat {
        grid-template-columns: 1fr;
        height: auto;
        overflow: visible;
    }
}
/* Tell the shared .chat-resizer which column width var to follow. Keeps
   one resizer CSS block working across /build and /plan without each
   layout hardcoding its own left-offset rule. */
.build-layout { --resizer-offset: var(--chat-w); }
.plan-layout  { --resizer-offset: var(--plan-chat-w); }
/* ── Plan guidance panel (replaces the chat on /plan) ─────────────────
   Static "step 2 of 5" overview that explains what the questionnaire
   on the right does. Same visual rhythm as the old chat sidebar
   (left-rule, fixed-width column, scrollable inner) so the page
   doesn't feel lopsided. Plain prose + numbered steps + a tip — no
   interactive controls, by design. */
.plan-guide {
    background: var(--surface);
    /* No right border — the column gap + the chat-resizer hover
       affordance carry the visual separation. The thin static line
       read as unnecessary chrome between the chat and the main pane. */
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    min-width: 0;
}
.plan-guide-inner {
    padding: 32px 28px 40px;
    max-width: 360px;
    margin: 0 auto;
}
.plan-guide-eyebrow {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent, #4f46e5);
    background: rgba(79, 70, 229, 0.08);
    padding: 4px 10px;
    border-radius: 999px;
    margin-bottom: 14px;
}
.plan-guide-title {
    font-family: 'Instrument Serif', serif;
    font-size: 28px;
    font-weight: 400;
    color: var(--ink-900);
    line-height: 1.15;
    margin: 0 0 10px;
}
.plan-guide-sub {
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink-600);
    margin: 0 0 28px;
}
.plan-guide-steps {
    list-style: none;
    margin: 0 0 24px;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.plan-guide-steps li {
    display: flex;
    gap: 14px;
    align-items: flex-start;
}
.plan-guide-step-num {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #0b0f19;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 600;
    margin-top: 1px;
}
.plan-guide-steps li > div {
    flex: 1; min-width: 0;
}
.plan-guide-steps strong {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-900);
    margin-bottom: 3px;
}
.plan-guide-steps p {
    margin: 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--ink-500);
}
.plan-guide-steps em {
    font-style: normal;
    font-weight: 600;
    color: var(--ink-700);
}
.plan-guide-tip {
    background: #fef9c3;
    border: 1px solid #fde68a;
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 24px;
}
.plan-guide-tip strong {
    display: block;
    font-size: 13px;
    color: #78350f;
    margin-bottom: 4px;
}
.plan-guide-tip p {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: #92400e;
}
.plan-guide-tip em {
    font-style: normal;
    font-weight: 600;
}
.plan-guide-back {
    display: inline-block;
    font-size: 13px;
    color: var(--ink-500);
    text-decoration: none;
}
.plan-guide-back:hover {
    color: var(--ink-900);
    text-decoration: underline;
}

.plan-chat {
    background: var(--surface);
    border-right: 1px solid var(--ink-100);
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    height: 100%;
    overflow: hidden;
}
.plan-layout > .plan-main {
    min-height: 0;
    overflow-y: auto;
    max-width: 100%;
}
.plan-chat-header {
    padding: 14px 18px;
    border-bottom: 1px solid var(--ink-100);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
}
.plan-chat-body {
    flex: 1;
    overflow-y: auto;
    padding: 18px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* ── Plan screen ───────────────────────────────────────────────────────── */
/* Flush-left layout: removed the historical `margin: 0 auto` centering
   so the questionnaire starts right after the chat divider instead of
   floating in the middle of the column with a fat empty gutter on its
   left. max-width still caps line length on huge monitors; padding is
   responsive (see breakpoints below). */
.plan-main { max-width: 880px; margin: 0; padding: 40px 40px 80px; }
.plan-hero { margin-bottom: 32px; }
.plan-tag {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 16px;
    letter-spacing: 0.02em;
}
.plan-title {
    font-size: 36px;
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1.15;
    margin: 0 0 10px;
}
.plan-sub { color: var(--ink-500); font-size: 16px; line-height: 1.6; max-width: 640px; margin: 0 0 22px; }
.plan-prompt {
    border: 1px solid var(--ink-100);
    border-left: 4px solid var(--accent);
    background: var(--surface);
    border-radius: var(--radius-md);
    padding: 14px 18px;
    font-size: 14px;
    color: var(--ink-700);
}
.plan-prompt-label {
    font-size: 11px; color: var(--ink-500); text-transform: uppercase; letter-spacing: 0.1em;
}
.plan-prompt p { margin: 6px 0 0; line-height: 1.5; }

.plan-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    margin-bottom: 28px;
}
.plan-card {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-lg);
    padding: 22px 22px 20px;
    box-shadow: var(--shadow-sm);
}
.plan-card h2 {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin: 0 0 14px;
}
.plan-card-wide { grid-column: span 2; }
.plan-card-hint { color: var(--ink-500); font-size: 13px; margin: -6px 0 12px; }

.plan-dl { display: grid; grid-template-columns: 120px 1fr; gap: 8px 18px; margin: 0; font-size: 14px; }
.plan-dl dt { color: var(--ink-500); }
.plan-dl dd { margin: 0; color: var(--ink-900); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

.pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 12px;
    font-weight: 500;
}
.pill.ghost { background: #f3f4f6; color: var(--ink-700); }
.pill.required { background: #fef3c7; color: #92400e; }

.plan-tickets { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.plan-tickets li {
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-md);
    padding: 14px 16px;
    background: #fafbff;
}
.plan-ticket-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.plan-ticket-name { font-weight: 600; }
.plan-ticket-price { color: var(--accent); font-weight: 600; }
.plan-ticket-desc { font-size: 13px; color: var(--ink-500); margin: 6px 0 0; line-height: 1.5; }
.plan-ticket-meta { display: flex; gap: 10px; font-size: 12px; color: var(--ink-500); margin-top: 8px; }

.plan-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.plan-field {
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    background: var(--surface);
}
.plan-field-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.plan-field-label { font-weight: 600; font-size: 14px; }
.plan-field-meta { display: flex; gap: 6px; margin-top: 6px; }
.plan-field-opts { font-size: 12px; color: var(--ink-500); margin: 8px 0 0; }

.plan-visual { display: flex; align-items: center; gap: 16px; }
.plan-swatch { width: 80px; height: 80px; border-radius: 16px; box-shadow: var(--shadow-sm); }
.plan-visual p { margin: 4px 0; font-size: 14px; color: var(--ink-700); }
.plan-visual code { background: #f3f4f6; padding: 2px 8px; border-radius: 6px; font-size: 12px; }

.plan-empty { color: var(--ink-500); font-size: 13px; margin: 0; }

.plan-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding-top: 8px;
}

/* ── Plan confirmation (simplified right panel) ────────────────────────── */
.plan-confirm {
    min-height: 0;
    overflow-y: auto;
    display: flex;
    justify-content: center;
    padding: 56px 32px 80px;
}
.plan-confirm-inner { max-width: 680px; width: 100%; }
.plan-confirm-title {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 44px;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--ink-900);
    margin: 10px 0 14px;
}
.plan-confirm-sub {
    font-size: 16px;
    color: var(--ink-500);
    line-height: 1.6;
    margin-bottom: 28px;
}
.plan-confirm-cta {
    display: flex;
    gap: 14px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 48px;
    padding-bottom: 32px;
    border-bottom: 1px solid var(--ink-100);
}
.plan-confirm-note {
    font-size: 13px;
    color: var(--ink-500);
    max-width: 300px;
    line-height: 1.45;
}
.btn-huge {
    padding: 16px 32px;
    font-size: 16px;
    letter-spacing: 0.005em;
    box-shadow: 0 8px 24px rgba(11, 15, 25, 0.12);
}
.btn-huge:hover { box-shadow: 0 12px 32px rgba(11, 15, 25, 0.16); transform: translateY(-1px); }

.plan-confirm-section { margin-bottom: 32px; }
.plan-confirm-section h3 {
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.plan-confirm-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.plan-confirm-list li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    font-size: 14px;
    color: var(--ink-900);
    flex-wrap: wrap;
}
.plan-confirm-list li strong { font-weight: 600; flex: 1; }
.plan-confirm-list li p {
    flex: 1 1 100%;
    margin: 4px 0 0;
    font-size: 13px;
    color: var(--ink-500);
    line-height: 1.45;
}
.plan-ro-price {
    font-weight: 600;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

/* ── Plan hero CTA ─────────────────────────────────────────────────────── */
.plan-hero-actions {
    margin-top: 20px;
    display: flex;
    gap: 16px;
    align-items: center;
    flex-wrap: wrap;
}
.plan-hero-hint {
    font-size: 13px;
    color: var(--ink-500);
    max-width: 320px;
    line-height: 1.45;
}
.btn-large { padding: 13px 24px; font-size: 15px; letter-spacing: 0.01em; }

/* ── Plan h2 inline add button ─────────────────────────────────────────── */
.plan-card h2 {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.plan-add-link {
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    background: var(--accent-soft);
    border: none;
    padding: 3px 10px;
    border-radius: 999px;
    cursor: pointer;
    text-transform: none;
    letter-spacing: normal;
}
.plan-add-link:hover { filter: brightness(0.97); }

/* ── Editable event dl ─────────────────────────────────────────────────── */
.plan-dl-editable {
    grid-template-columns: 110px 1fr;
    align-items: center;
    gap: 10px 18px;
}
.plan-dl-editable dt { font-size: 12px; padding-top: 6px; }
.plan-input {
    width: 100%;
    border: 1px solid transparent;
    background: transparent;
    padding: 6px 8px;
    border-radius: 6px;
    font-family: inherit;
    font-size: 14px;
    color: var(--ink-900);
    transition: border-color 0.12s, background 0.12s;
}
.plan-input:hover { border-color: var(--ink-100); background: var(--surface); }
.plan-input:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--surface);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.12);
}
.plan-input-name { font-weight: 600; font-size: 15px; }
.plan-input-select { cursor: pointer; }
.plan-dates { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.plan-arrow { color: var(--ink-500); font-size: 12px; padding: 0 2px; }
.plan-add-end, .plan-remove-end {
    font-size: 12px; color: var(--ink-500);
    background: transparent; border: 1px dashed var(--ink-100);
    padding: 5px 10px; border-radius: 6px; cursor: pointer;
}
.plan-add-end:hover { color: var(--accent); border-color: var(--accent); }
.plan-remove-end {
    border-radius: 50%; width: 22px; height: 22px;
    padding: 0; display: inline-flex; align-items: center; justify-content: center;
    border-style: solid;
}
.plan-remove-end:hover { color: var(--danger); border-color: var(--danger); }

/* ── Editable tickets ──────────────────────────────────────────────────── */
.plan-tickets-editable li.plan-ticket-edit {
    display: flex; flex-direction: column; gap: 6px;
    padding: 12px 14px;
}
.plan-ticket-row { display: flex; gap: 8px; align-items: center; }
.plan-price-input {
    display: inline-flex; align-items: center;
    background: var(--surface); border: 1px solid var(--ink-100);
    border-radius: 6px; overflow: hidden; width: 112px;
    flex-shrink: 0;
}
.plan-price-symbol { padding: 0 6px 0 10px; color: var(--ink-500); font-size: 13px; }
.plan-price-input input {
    border: none; outline: none; width: 100%;
    padding: 7px 8px 7px 0;
    font-size: 13px; color: var(--ink-900);
    background: transparent;
    font-family: inherit;
}
.plan-ticket-edit .plan-input-desc {
    font-size: 13px; color: var(--ink-500);
}
.plan-row-delete {
    flex-shrink: 0;
    width: 26px; height: 26px;
    border: 1px solid var(--ink-100);
    background: var(--surface);
    color: var(--ink-500);
    border-radius: 50%;
    font-size: 16px;
    cursor: pointer;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color 0.12s, border-color 0.12s;
}
.plan-row-delete:hover { color: var(--danger); border-color: var(--danger); }

/* ── Editable fields ───────────────────────────────────────────────────── */
.plan-fields-editable { display: flex; flex-direction: column; gap: 6px; }
.plan-field-edit {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    background: var(--surface);
    transition: border-color 0.12s;
}
.plan-field-edit:hover { border-color: #c7d2fe; }
.plan-field-edit .plan-field-label-input {
    flex: 1; font-weight: 500; font-size: 14px;
}
.plan-field-edit .toggle { flex-shrink: 0; }
.plan-field-edit .plan-field-type {
    flex-shrink: 0;
    text-transform: lowercase;
    font-variant: all-small-caps;
    letter-spacing: 0.04em;
}

.btn-primary {
    background: var(--ink-900);
    color: #fff;
    border: none;
    padding: 12px 22px;
    border-radius: var(--radius-md);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.08s, opacity 0.15s;
}
.btn-primary:hover { opacity: 0.94; }
.btn-primary:active { transform: scale(0.985); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-ghost {
    color: var(--ink-500);
    background: transparent;
    border: 1px solid var(--ink-100);
    padding: 11px 18px;
    border-radius: var(--radius-md);
    font-size: 14px;
    cursor: pointer;
}
.btn-ghost:hover { background: #f3f4f6; }

/* ── Build screen ──────────────────────────────────────────────────────── */
.build-layout {
    display: grid;
    /* Chat column width comes from a custom property so the resizer can
       mutate it live (JS writes --chat-w on this element, CSS binds it
       to grid-template-columns). Defaults to 420px to match the v1
       reference width; min/max cap how far drag can go. */
    --chat-w: 420px;
    --chat-w-min: 300px;
    --chat-w-max: 640px;
    grid-template-columns: var(--chat-w) 1fr;
    gap: 0;
    height: calc(100vh - 56px);    /* fixed, so each pane owns its own scroll */
    overflow: hidden;
    position: relative;             /* anchor for the drawer + resizer */
}

/* Draggable split between chat + preview. 6px hit-zone, 1px visible
   rule unless hovered/dragging. Sits centred on the grid gap so the
   click target spans both sides of the column border. */
.chat-resizer {
    position: absolute;
    top: 0;
    left: var(--resizer-offset, var(--chat-w, 420px));
    width: 10px;
    height: 100%;
    margin-left: -5px;
    z-index: 15;
    cursor: col-resize;
    user-select: none;
}
.chat-resizer::after {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 4px; width: 2px;
    background: transparent;
    border-radius: 2px;
    transition: background 0.12s;
}
.chat-resizer:hover::after,
.chat-resizer.dragging::after {
    background: rgba(79, 70, 229, 0.45);
}
body.chat-resizing { cursor: col-resize; user-select: none; }
body.chat-resizing iframe { pointer-events: none; }  /* stop iframe from eating mousemove */
.build-pane {
    border-right: 1px solid var(--ink-100);
    background: var(--surface);
    min-width: 0;
    min-height: 0;                  /* let grid child shrink so inner scroll works */
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.build-pane:last-child { border-right: none; }
/* Chat panel has no right border — the chat-resizer's hover affordance
   carries the divider role on demand. The static 1px line read as
   unnecessary chrome between the chat and the preview. The preview→
   tweaks divider keeps its border because the tweaks drawer slides
   over the preview and needs the hard edge for separation. */
.build-pane.chat { border-right: none; }

/* Advanced panel — slides in from the right over the preview pane.
   Floats instead of occupying a grid column so the preview iframe
   doesn't reflow when the drawer opens. Shadow on the left edge
   provides separation without a hard border. */
.build-pane.builder {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 420px;
    max-width: 100%;
    z-index: 20;
    border-left: 1px solid var(--ink-100);
    border-right: none;
    box-shadow: -12px 0 32px -16px rgba(15, 23, 42, 0.18);
    transform: translateX(100%);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
.build-layout[data-advanced="on"] .build-pane.builder {
    transform: translateX(0);
}

/* Toggle button label swap — two spans, one shown per state. */
.build-layout[data-advanced="on"] #btn-toggle-advanced .adv-toggle-open { display: none; }
.build-layout[data-advanced="off"] #btn-toggle-advanced .adv-toggle-close { display: none; }
.build-layout[data-advanced="on"] #btn-toggle-advanced {
    background: var(--ink-900);
    color: #fff;
    border-color: var(--ink-900);
}

.pane-header {
    padding: 14px 18px;
    border-bottom: 1px solid var(--ink-100);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}
.pane-title { font-size: 13px; font-weight: 600; color: var(--ink-700); text-transform: uppercase; letter-spacing: 0.08em; }
.pane-body { flex: 1; overflow-y: auto; padding: 18px; min-height: 0; }

/* Chat pane — targets both id-based wrappers (#chat-messages on /build
   and #plan-chat-messages on /plan) + the legacy .chat-messages class,
   so messages always have breathing room. Earlier the /build wrapper
   only had .pane-body so bubbles stacked with zero gap. */
.chat-messages,
#chat-messages,
#plan-chat-messages {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-bottom: 8px;
}
/* v1-inspired bubble layout: avatar circle + rounded pill beside it.
   The .chat-msg element is a flex row; addChatMsg / addPlanMsg build
   it as <div class="chat-msg {who}"><span class="chat-msg-avatar">..</span>
   <span class="chat-msg-bubble">text</span></div>. User messages flow
   right (row-reverse), AI messages flow left. Slight corner-trim on the
   bubble adjacent to the avatar mimics the v1 speech-bubble feel. */
.chat-msg {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    max-width: 94%;
    background: transparent;
    padding: 0;
    border-radius: 0;
    border: 0;
}
.chat-msg.user { align-self: flex-end; flex-direction: row-reverse; }
.chat-msg.ai   { align-self: flex-start; }

.chat-msg-avatar {
    width: 32px; height: 32px;
    flex-shrink: 0;
    border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700;
    letter-spacing: 0.02em;
}
.chat-msg.user .chat-msg-avatar {
    background: var(--ink-900); color: #fff;
    font-size: 11px;
}
.chat-msg.ai .chat-msg-avatar {
    background: #eef0f6; color: var(--ink-900);
    font-size: 16px;                 /* Fallback letter "e" dominates the circle */
    font-weight: 700;
    border: 1px solid var(--ink-100);
}
/* Image-backed variant for the e2m AI avatar — the standalone "e" mark
   fills the circle edge-to-edge. object-fit: cover + 100% size means
   the mark crops to fill regardless of source aspect ratio, so the
   avatar reads as the brand icon at 32px rather than a small logo
   floating inside a mostly-empty tile. */
.chat-msg-avatar.chat-msg-avatar-logo {
    background: #fff;
    padding: 0;
    overflow: hidden;
}
.chat-msg-avatar.chat-msg-avatar-logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* Source PNGs often ship with a safety margin baked in; scaling up
       inside the clipped circle zooms past that whitespace so the mark
       reads at full strength at 32px. The parent's `overflow: hidden`
       keeps it pinned to the circle. */
    transform: scale(1.4);
}

.chat-msg-bubble {
    padding: 12px 16px;
    border-radius: 20px;
    font-size: 14.5px;
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
    max-width: 100%;
}
.chat-msg.user .chat-msg-bubble {
    background: var(--ink-900);
    color: #fff;
    border-bottom-right-radius: 6px;
}
.chat-msg.ai .chat-msg-bubble {
    background: #f4f4f6;
    color: var(--ink-900);
    border-bottom-left-radius: 6px;
}
.chat-msg.ai.muted .chat-msg-bubble { font-style: italic; color: var(--ink-500); }

/* Awaiting-input affordance for clarification bubbles. Pulled in by
   the chat handler when ChatResult.awaiting_user_input is true —
   draws attention to the assistant's "could you rephrase?" / "do
   you want X or Y?" without the rotating ring that earlier read as
   a loading state.

   Now: a static gradient ring around the whole bubble (indigo →
   violet → blue) so the WHOLE box visibly says "this needs your
   input". Implementation pattern is the standard padded gradient
   border with mask-composite — the gradient fills a ::before
   layer, and a content-box mask carves out the interior so only
   the border edge paints. No rotation, no flicker; one short
   entry pulse to draw the eye, then the ring stays static.

   prefers-reduced-motion drops the entry pulse, keeps the static
   ring. Fallback for browsers without mask-composite (very rare):
   a solid indigo border via @supports negation. */
.chat-msg.ai .chat-msg-bubble.is-awaiting-input {
    position: relative;
    isolation: isolate;
    background-clip: padding-box;
}
.chat-msg.ai .chat-msg-bubble.is-awaiting-input::before {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: inherit;
    padding: 2px;
    background: linear-gradient(
        135deg,
        #6366f1 0%,
        #8b5cf6 35%,
        #ec4899 65%,
        #6366f1 100%
    );
    -webkit-mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
            mask:
        linear-gradient(#000 0 0) content-box,
        linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    z-index: -1;
    animation: chat-await-glow 900ms cubic-bezier(0.16, 1, 0.3, 1) 1;
}
@keyframes chat-await-glow {
    0%   { opacity: 0;   transform: scale(0.985); }
    60%  { opacity: 1;   transform: scale(1.008); }
    100% { opacity: 1;   transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
    .chat-msg.ai .chat-msg-bubble.is-awaiting-input::before {
        animation: none;
    }
}
/* Fallback: browsers that don't support mask-composite get a
   solid indigo border instead of the gradient. Visually less
   striking but the affordance is still legible. */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
    .chat-msg.ai .chat-msg-bubble.is-awaiting-input {
        box-shadow: 0 0 0 2px #6366f1;
    }
    .chat-msg.ai .chat-msg-bubble.is-awaiting-input::before { display: none; }
}

/* ── Markdown rendering inside chat bubbles ────────────────────────
   The chat handler now passes the assistant's reply through a tiny
   markdown formatter (build.html : renderMarkdownInline) so **bold**,
   *italic*, lists, code, and links render properly instead of leaking
   raw asterisks. Below: the typography for those rendered elements,
   scoped to .chat-msg-bubble so no other surface inherits.

   Conservative palette — same ink colours as the bubble body so the
   visual hierarchy is "bold = emphasis", not "bold = different
   colour". Lists use compact margins so the bubble doesn't grow
   tall on a 3-bullet ask. */
.chat-msg-bubble strong { font-weight: 600; color: inherit; }
.chat-msg-bubble em { font-style: italic; }
.chat-msg-bubble code {
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    font-size: 0.92em;
    background: rgba(15, 23, 42, 0.06);
    color: var(--ink-900);
    padding: 1px 5px;
    border-radius: 4px;
}
.chat-msg.user .chat-msg-bubble code {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
}
.chat-msg-bubble a {
    color: var(--accent, #4f46e5);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.chat-msg-bubble ul,
.chat-msg-bubble ol {
    margin: 6px 0 6px 0;
    padding-left: 22px;
}
.chat-msg-bubble li { margin: 2px 0; }
.chat-msg-bubble p { margin: 0 0 8px; }
.chat-msg-bubble p:last-child { margin-bottom: 0; }

/* Comfy chat composer — generous padding, multiline by default, voice
   button for hands-free prompting. Shared by /plan and /build. */
.chat-input {
    border-top: 1px solid var(--ink-100);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex-shrink: 0;
    background: var(--surface);
}
.chat-input textarea {
    width: 100%;
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    padding: 14px 16px;
    font-family: inherit;
    font-size: 15px;
    resize: none;
    /* Generous default so short prompts land in a roomy box; grows via
       JS autoGrowChat up to the CSS ceiling below, then scrolls within. */
    min-height: 120px;
    max-height: min(48vh, 420px);
    overflow-y: auto;
    line-height: 1.5;
    background: var(--canvas);
    transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.chat-input textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
    background: #fff;
}
.chat-input-actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
.chat-input-hint {
    font-size: 11.5px;
    color: var(--ink-500);
    display: flex;
    align-items: center;
    gap: 6px;
}
.chat-input-hint kbd {
    background: #f3f4f6;
    border: 1px solid var(--ink-100);
    border-radius: 4px;
    padding: 1px 6px;
    font-family: inherit;
    font-size: 10.5px;
    color: var(--ink-700);
}
.chat-input-buttons { display: flex; gap: 8px; }
.chat-input button {
    border: none;
    background: var(--ink-900);
    color: #fff;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    cursor: pointer;
    transition: transform 0.08s, background 0.15s, box-shadow 0.15s;
}
.chat-input button:hover { background: #1f2937; }
.chat-input button:active { transform: scale(0.94); }
.chat-input button:disabled { opacity: 0.4; cursor: not-allowed; }
.chat-input .btn-voice {
    background: var(--surface);
    color: var(--ink-700);
    border: 1px solid var(--ink-100);
}
.chat-input .btn-voice:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.chat-input .btn-voice.recording {
    background: #fef2f2;
    color: #dc2626;
    border-color: #fca5a5;
    box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.12);
    animation: mic-pulse 1.4s ease-in-out infinite;
}
@keyframes mic-pulse {
    0%, 100% { box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.12); }
    50%      { box-shadow: 0 0 0 8px rgba(220, 38, 38, 0.22); }
}

/* Voice dictation textarea states. .is-dictating runs while the
   recogniser is actively listening — soft red ring matches the mic
   button. .is-review parks after auto-stop (1.8s silence) so the
   organiser sees a "transcript ready, review + send" cue instead of
   the form auto-firing on noisy speech. .is-ready-pulse on the Send
   button draws the eye to the next step once. */
#chat-textarea.is-dictating,
#plan-chat-textarea.is-dictating {
    border-color: #fca5a5 !important;
    background: #fffafa !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.10) !important;
}
#chat-textarea.is-review,
#plan-chat-textarea.is-review {
    border-color: #93c5fd !important;
    background: #f8fbff !important;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.10) !important;
}
.is-ready-pulse {
    animation: send-ready 0.8s ease-out 3;
}
@keyframes send-ready {
    0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(79, 70, 229, 0); }
    50%      { transform: scale(1.06); box-shadow: 0 0 0 6px rgba(79, 70, 229, 0.22); }
}

/* Middle preview pane */
.preview-pane { background: #f4f5f7; align-items: stretch; }
.preview-toolbar {
    padding: 10px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--ink-100);
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    justify-content: flex-start;
}
.preview-toggles { display: flex; gap: 4px; background: #f3f4f6; border-radius: 10px; padding: 3px; }
.preview-toggles button {
    border: none;
    background: transparent;
    width: 32px;
    height: 28px;
    border-radius: 8px;
    color: var(--ink-500);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
.preview-toggles button:hover { color: var(--ink-900); }
.preview-toggles button.active { background: var(--surface); color: var(--ink-900); box-shadow: var(--shadow-sm); }
.preview-toggles button svg { display: block; }

.preview-mode-toggle { display: flex; gap: 4px; background: #f3f4f6; border-radius: 10px; padding: 3px; }
.preview-mode-toggle button { border: none; background: transparent; padding: 6px 12px; border-radius: 8px; font-size: 13px; cursor: pointer; color: var(--ink-500); }
.preview-mode-toggle button.active { background: var(--ink-900); color: #fff; }
.preview-mode-toggle button { white-space: nowrap; }
.preview-mode-toggle { margin-right: auto; }

/* Vertical / Horizontal ticket-layout toggle in the preview toolbar.
   Matches the device-toggle visual language (pill group, soft-grey
   container, subtle active card) so the toolbar reads as one set of
   coordinated controls. The "Change layout" label sits inline before
   the buttons because the toggle is the only one that names the
   property it controls — devices and modes are self-evident from the
   icons, layout needs the word. */
.preview-layout-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.preview-layout-toggle .preview-layout-label {
    font-size: 12px;
    color: var(--ink-500);
    white-space: nowrap;
}
.preview-layout-toggle > button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 0;
    background: #f3f4f6;
    padding: 6px 10px;
    border-radius: 8px;
    font-size: 12.5px;
    color: var(--ink-500);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.preview-layout-toggle > button:hover { color: var(--ink-900); }
.preview-layout-toggle > button.active {
    background: var(--ink-900);
    color: #fff;
}
.preview-layout-toggle > button svg { display: block; }

.preview-stage {
    flex: 1;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 28px;
    overflow: auto;
}
.preview-frame {
    background: var(--surface);
    border-radius: 18px;
    box-shadow: 0 20px 60px rgba(15, 23, 42, 0.12);
    overflow: hidden;
    width: 100%;
    max-width: 1180px;
    transition: max-width 0.25s ease, width 0.25s ease;
}
.preview-frame.device-mobile { max-width: 392px; border-radius: 32px; }
.preview-frame.device-tablet { max-width: 820px; border-radius: 24px; }

.preview-iframe {
    /* Render the iframe at a slightly wider viewport and scale it back
       so organisers see more of the hero + reg form above the fold —
       the preview pane is narrower than a real desktop, and without a
       zoom compensation the landing looks crammed. */
    width: 108.7%;
    margin-left: -4.35%;
    min-height: 826px;
    transform: scale(0.92);
    transform-origin: top center;
    border: 0;
    display: block;
    background: #fff;
}
/* Mobile/tablet previews are already narrow phone-shaped simulations —
   no zoom-out, they'd shrink to unreadable. */
.preview-frame.device-mobile .preview-iframe,
.preview-frame.device-tablet .preview-iframe {
    width: 100%;
    margin-left: 0;
    min-height: 760px;
    transform: none;
}

/* Right builder pane */
.builder-section { margin-bottom: 22px; }
.builder-section-title {
    font-size: 11px;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin: 0 0 10px;
    display: flex; justify-content: space-between; align-items: center;
}
.builder-section-title .btn-add-inline {
    background: var(--accent-soft); color: var(--accent); border: none;
    padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; cursor: pointer;
}
.builder-section-title .btn-add-inline:hover { filter: brightness(0.97); }

.builder-row {
    background: #fafbff;
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 8px;
}
.builder-row-head { display: flex; gap: 8px; align-items: center; }
.builder-row-head input.label {
    flex: 1; border: 1px solid transparent; background: transparent;
    font-size: 14px; font-weight: 500; padding: 6px 8px; border-radius: 6px;
}
.builder-row-head input.label:focus { background: var(--surface); border-color: var(--ink-100); outline: none; }
.builder-row-head select,
.builder-row-head input[type="number"],
.builder-row-head input[type="text"] {
    border: 1px solid var(--ink-100); background: var(--surface); border-radius: 6px;
    padding: 6px 8px; font-size: 13px;
}
.builder-row-head .mini-btn {
    background: transparent; border: none; color: var(--ink-500); cursor: pointer; padding: 4px 6px; border-radius: 6px;
}
.builder-row-head .mini-btn:hover { background: var(--ink-100); color: var(--danger); }

/* Landing-section rows (Speakers / Agenda / Sponsors). Same chrome
   as ticket / field rows but with a two-column grid body so the
   larger content set (photo url, bio, linkedin, etc.) doesn't
   overflow. .full spans both columns for long URLs / textareas. */
.landing-rows { display: flex; flex-direction: column; gap: 8px; }
.builder-row-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}
.builder-row-grid > .full { grid-column: 1 / -1; }
.builder-row-grid input[type="text"],
.builder-row-grid input[type="url"],
.builder-row-grid input[type="datetime-local"],
.builder-row-grid textarea {
    width: 100%;
    padding: 7px 9px;
    font-size: 12.5px;
    border: 1px solid var(--ink-100);
    background: var(--surface);
    border-radius: 6px;
    color: var(--ink-900);
    font: inherit;
    font-size: 12.5px;
}
.builder-row-grid textarea { resize: vertical; min-height: 44px; }
.builder-row-grid input:focus,
.builder-row-grid textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.08);
}
.builder-row-thumb {
    margin-top: 4px;
    width: 56px; height: 56px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--ink-100);
    border: 1px solid var(--ink-100);
}
.builder-row-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.btn-row-remove {
    background: transparent;
    border: 1px solid transparent;
    color: var(--ink-500);
    cursor: pointer;
    padding: 4px 9px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1;
}
.btn-row-remove:hover { background: #fef2f2; color: #991b1b; border-color: #fecaca; }

/* Inline "📎 Upload" trigger next to a URL field. Flex row with the
   input taking the remaining width; button sits flush against the
   input's right edge so the pair reads as a single control. */
.row-field-with-upload {
    display: flex;
    gap: 6px;
    align-items: stretch;
}
.row-field-with-upload input { flex: 1; min-width: 0; }
.btn-row-upload {
    flex-shrink: 0;
    padding: 7px 12px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-900);
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 6px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.12s, border-color 0.12s;
}
.btn-row-upload:hover { background: #eef2ff; border-color: #c7d2fe; color: #3730a3; }
.resource-row-hint {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 10.5px;
    color: var(--ink-500);
    background: #f9fafb;
    border: 1px dashed var(--ink-100);
    padding: 4px 8px;
    border-radius: 4px;
    word-break: break-all;
}

.builder-row-meta { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-size: 12px; color: var(--ink-500); }
.builder-row-meta label { display: flex; align-items: center; gap: 4px; cursor: pointer; }
.builder-row-meta input[type="date"] {
    border: 1px solid var(--ink-100); background: var(--surface);
    border-radius: 6px; padding: 4px 6px; font-size: 12px; color: var(--ink-700);
}
.builder-row-meta .options-input {
    flex: 1 1 100%; border: 1px solid var(--ink-100); background: var(--surface); border-radius: 6px;
    padding: 6px 8px; font-size: 12px; color: var(--ink-700);
}
/* Live-inventory pill next to the Limit cell — mirrors the "Only N
   left" badge the embed shows attendees, so organisers don't have to
   flip to the Registrations screen to see how fast a tier is filling. */
.tier-remaining {
    display: inline-flex; align-items: center;
    padding: 2px 7px; border-radius: 999px;
    font-size: 10.5px; font-weight: 600;
    background: var(--ink-100); color: var(--ink-700);
    letter-spacing: 0.03em;
}
.tier-remaining-low { background: #fef2f2; color: #b91c1c; }

.event-meta-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.event-meta-grid label { font-size: 11px; color: var(--ink-500); display: block; margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.08em; }
.event-meta-grid input,
.event-meta-grid select,
.event-meta-grid textarea {
    width: 100%; border: 1px solid var(--ink-100); background: var(--surface);
    border-radius: var(--radius-sm); padding: 8px 10px; font-size: 13px; font-family: inherit;
}
.event-meta-grid textarea { min-height: 58px; resize: vertical; }
.event-meta-grid .full { grid-column: span 2; }

.builder-footer {
    flex-shrink: 0; padding: 14px 18px; border-top: 1px solid var(--ink-100); background: var(--surface);
    display: flex; justify-content: space-between; align-items: center; gap: 8px;
}
.save-status { font-size: 12px; color: var(--ink-500); }
.save-status.saving { color: var(--warn); }
.save-status.saved { color: var(--success); }

/* ── Publish screen ────────────────────────────────────────────────────── */
.publish-main { max-width: 1100px; margin: 0 auto; padding: 40px 24px 80px; }
.publish-hero { margin-bottom: 28px; }
.publish-hero h1 { font-size: 32px; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 6px; }
.publish-hero p { color: var(--ink-500); margin: 0; font-size: 15px; }
.publish-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.publish-card {
    background: var(--surface); border: 1px solid var(--ink-100);
    border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-sm);
}
.publish-card h2 {
    font-size: 14px; font-weight: 600; color: var(--ink-500);
    text-transform: uppercase; letter-spacing: 0.08em; margin: 0 0 14px;
}
.publish-card-wide { grid-column: span 2; }

.payment-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 14px; }
.payment-choice {
    border: 2px solid var(--ink-100); border-radius: var(--radius-md);
    padding: 14px 16px; cursor: pointer; transition: border 0.12s, background 0.12s;
    display: flex; flex-direction: column; gap: 6px;
}
.payment-choice.active { border-color: var(--ink-900); background: #fafafa; }
.payment-choice h3 { margin: 0; font-size: 15px; }
.payment-choice p { margin: 0; font-size: 13px; color: var(--ink-500); line-height: 1.45; }

/* Legacy .provider-row / .provider-pill rules retired — superseded by the
   .provider-pill-card grid on /v3/studio/{id}/payments. Removing them
   prevents display:flex leaking onto <tr class="provider-row"> in the
   admin payments table and mangling the row. */

.publish-previews { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 8px; }
.preview-tile { border: 1px solid var(--ink-100); border-radius: var(--radius-md); overflow: hidden; background: #f3f4f6; }
.preview-tile-head {
    padding: 8px 12px; background: var(--surface); border-bottom: 1px solid var(--ink-100);
    font-size: 12px; color: var(--ink-500); display: flex; justify-content: space-between; align-items: center;
}
.preview-tile iframe { width: 100%; height: 360px; border: 0; background: var(--surface); display: block; }

.embed-block {
    margin-top: 10px;
    background: #0b0f19; color: #e5e7eb; border-radius: var(--radius-md);
    padding: 12px 14px; font-family: 'SF Mono', Menlo, Consolas, monospace;
    font-size: 12px; overflow-x: auto; white-space: pre; position: relative;
}
.embed-block button {
    position: absolute; top: 8px; right: 8px; background: rgba(255, 255, 255, 0.12);
    color: #fff; border: none; padding: 4px 10px; border-radius: 6px; font-size: 11px; cursor: pointer;
}

.publish-footer { margin-top: 22px; display: flex; justify-content: space-between; align-items: center; }
.live-banner {
    background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46;
    padding: 14px 16px; border-radius: var(--radius-md); margin-bottom: 18px;
    display: flex; gap: 14px; align-items: center;
}
.live-banner a { color: inherit; text-decoration: underline; font-weight: 600; }

/* ── Plan compact prompt echo ─────────────────────────────────────────── */
.plan-prompt-compact {
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-md);
    background: var(--surface);
    overflow: hidden;
}
.plan-prompt-compact summary {
    list-style: none;
    cursor: pointer;
    padding: 12px 16px;
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 13px;
}
.plan-prompt-compact summary::-webkit-details-marker { display: none; }
.plan-prompt-label {
    font-size: 10px;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    flex-shrink: 0;
}
.plan-prompt-snippet { color: var(--ink-700); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-prompt-edit { font-size: 12px; color: var(--ink-500); text-decoration: none; }
.plan-prompt-edit:hover { color: var(--accent); text-decoration: underline; }
.plan-prompt-compact p { padding: 0 16px 14px; font-size: 13px; line-height: 1.55; color: var(--ink-700); margin: 0; }

/* ── Count pill + collapsibles ─────────────────────────────────────────── */
.count-pill {
    display: inline-block;
    margin-left: 6px;
    min-width: 20px;
    padding: 1px 7px;
    background: var(--ink-100);
    color: var(--ink-700);
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    text-align: center;
    letter-spacing: normal;
    text-transform: none;
}
.builder-section-collapsible { padding: 0; background: transparent; border: none; }
.builder-section-collapsible > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 0 10px;
    margin: 0 0 10px;
    position: relative;
}
.builder-section-collapsible > summary::-webkit-details-marker { display: none; }
.builder-section-collapsible > summary::after {
    content: '▾';
    color: var(--ink-500);
    font-size: 10px;
    transition: transform 0.2s;
    margin-left: 8px;
}
.builder-section-collapsible[open] > summary::after { transform: rotate(180deg); }
.builder-section-collapsible .collapsible-hint { font-size: 11px; color: var(--ink-500); text-transform: none; letter-spacing: normal; font-weight: 400; }

/* ── Grouped field rows (Form fields panel) ───────────────────────────── */
.field-group { border: none; padding: 0; margin-bottom: 14px; }
.field-group > summary {
    list-style: none;
    cursor: pointer;
    padding: 8px 10px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    gap: 10px;
    background: #f9fafb;
    border: 1px solid transparent;
    transition: background 0.15s;
    margin-bottom: 6px;
}
.field-group > summary::-webkit-details-marker { display: none; }
.field-group > summary:hover { background: var(--ink-100); }
.field-group[open] > summary { background: var(--surface); border-color: var(--ink-100); }
.field-group > summary::before {
    content: '▸';
    color: var(--ink-500);
    font-size: 10px;
    transition: transform 0.15s;
    flex-shrink: 0;
}
.field-group[open] > summary::before { transform: rotate(90deg); }
.fg-title { font-size: 13px; font-weight: 600; color: var(--ink-900); }
.fg-hint { font-size: 11px; color: var(--ink-500); flex: 1; }
.fg-count {
    background: var(--ink-100); color: var(--ink-700);
    font-size: 10px; font-weight: 700;
    padding: 1px 7px; border-radius: 999px;
}
/* Rename affordance on custom section headers. Only renders for
   organiser-defined sections — the preset keys (contact/professional/
   …) stay read-only so their semantics survive. Opacity 0.6 by default
   so it fades into the summary row, lifts to full opacity on hover.
   The click handler swaps .fg-title for a bare <input> styled below,
   so committing is just Enter/blur — no save button needed. */
.fg-rename {
    background: transparent; border: 0; cursor: pointer;
    font-size: 12px; color: var(--ink-500);
    padding: 2px 6px; border-radius: 4px;
    opacity: 0.6; transition: opacity 120ms, background 120ms;
}
.field-group > summary:hover .fg-rename { opacity: 1; }
.fg-rename:hover { background: var(--ink-100); color: var(--ink-900); }
.fg-title-input {
    font-size: 13px; font-weight: 600; color: var(--ink-900);
    padding: 2px 6px; border: 1px solid var(--accent, #4f46e5);
    border-radius: 5px; outline: none;
    min-width: 120px; max-width: 240px;
    background: #fff;
}

.field-row {
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    background: var(--surface);
    margin: 4px 0 6px 20px;
    overflow: hidden;
    transition: box-shadow 0.15s, border-color 0.15s;
}
.field-row:hover { border-color: #c7d2fe; }
.field-row.expanded { box-shadow: 0 4px 12px rgba(15, 23, 42, 0.06); border-color: #c7d2fe; }

.field-row-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    cursor: default;
}
.field-expand {
    width: 18px; height: 18px; flex-shrink: 0;
    border: none; background: transparent; color: var(--ink-500);
    font-size: 11px; cursor: pointer; padding: 0;
    transition: transform 0.15s;
}
.field-row.expanded .field-expand { transform: rotate(90deg); }
.field-row-label {
    flex: 1;
    font-size: 13px; font-weight: 500; color: var(--ink-900);
    cursor: pointer;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.field-row-type {
    font-size: 11px; color: var(--ink-500);
    padding: 2px 8px; border-radius: 999px;
    background: #f3f4f6;
    cursor: pointer;
    flex-shrink: 0;
}
.field-row .toggle { margin: 0; flex-shrink: 0; }
.field-row .mini-btn { flex-shrink: 0; }
/* ↑ / ↓ reorder handles — lighter touch than the ✕ delete so the eye
   reads Remove as the scariest action. Disabled-look when the field is
   already at the section's extremes (handled by JS guarding the swap). */
.field-row .field-up, .field-row .field-down {
    font-size: 13px;
    line-height: 1;
    opacity: 0.55;
    transition: opacity 0.15s, background 0.15s;
}
.field-row .field-up:hover, .field-row .field-down:hover {
    opacity: 1;
    background: var(--ink-100);
    color: var(--ink-900);
}
.field-row .field-remove:hover { background: #fef2f2; color: var(--danger, #dc2626); }

/* Duplicate-field warning. Soft amber so it reads as "heads up" rather
   than "error" — duplicates are usually a UX mistake the organiser can
   accept or fix in one click, not a hard validation failure. Lives at
   the top of #fields-list and mirrors the visual weight of a save
   status pill so it doesn't dominate the editor. */
.dup-warning {
    margin: 0 0 10px;
    padding: 10px 12px;
    border: 1px solid #fcd9a3;
    background: #fff8ec;
    border-radius: 8px;
    font-size: 12.5px;
    color: #7c4a03;
}
.dup-warning-head {
    display: flex; align-items: center; gap: 6px;
    font-weight: 600; margin-bottom: 6px;
    color: #92400e;
}
.dup-warning-icon { font-size: 13px; }
.dup-warning-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 4px 0;
    border-top: 1px dashed #f3d9a8;
}
.dup-warning-row:first-of-type { border-top: none; }
.dup-warning-text { flex: 1; line-height: 1.4; }
.dup-warning-actions { display: flex; gap: 6px; flex-shrink: 0; }
.dup-action {
    font-size: 11.5px; font-weight: 500;
    padding: 4px 10px; border-radius: 6px;
    border: 1px solid transparent; cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}
.dup-action.dup-remove {
    background: #fff; border-color: #fcd9a3; color: #7c4a03;
}
.dup-action.dup-remove:hover { background: #fef3c7; border-color: #f59e0b; }
.dup-action.dup-keep {
    background: transparent; border-color: transparent; color: #92400e;
}
.dup-action.dup-keep:hover { background: #fef3c7; }

/* Inline chip next to the field label — stays visible after "Keep
   both" dismisses the banner so the duplicate row is never silently
   accepted. Same palette as the banner. */
.field-row-dup {
    font-size: 10.5px; font-weight: 600;
    padding: 2px 7px; border-radius: 999px;
    background: #fff3d6; color: #92400e;
    border: 1px solid #fcd9a3;
    flex-shrink: 0;
    letter-spacing: 0.01em;
}
.field-row-head.is-duplicate .field-row-label { color: #7c4a03; }

/* Drag-handle column. The handle is the only legal drag-start surface
   on the row — outside it the body/inputs work normally. cursor: grab
   tells the eye it's draggable; on active drag the body cursor flips
   to grabbing via [draggable].is-dragging below. */
.field-row .field-drag {
    width: 16px; height: 18px; flex-shrink: 0;
    border: none; background: transparent; padding: 0;
    color: var(--ink-300, #cbd5e1);
    font-size: 14px; line-height: 1; letter-spacing: -2px;
    cursor: grab;
    opacity: 0.7;
    transition: color 0.15s, opacity 0.15s;
    user-select: none;
}
.field-row:hover .field-drag { color: var(--ink-500); opacity: 1; }
.field-row .field-drag:active { cursor: grabbing; }

/* In-flight drag visual — source row dims, target row gets a coloured
   line on the side it'll drop to so the user can predict the result
   without releasing. The 2px insets keep the indicator off the section
   border so it reads as a per-row affordance. */
.field-row.is-dragging {
    opacity: 0.45;
    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.12);
    cursor: grabbing;
}
.field-row.drop-above { box-shadow: inset 0 3px 0 0 #4f46e5; }
.field-row.drop-below { box-shadow: inset 0 -3px 0 0 #4f46e5; }
.field-row.drop-above.drop-below { box-shadow: inset 0 3px 0 0 #4f46e5; } /* belt+braces */

.field-row-body {
    display: none;
    padding: 8px 14px 14px 36px;
    border-top: 1px solid #f3f4f6;
    gap: 10px;
    grid-template-columns: 1fr 1fr;
}
.field-row.expanded .field-row-body { display: grid; }
.field-row-body label {
    font-size: 11px;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.field-row-body input,
.field-row-body select {
    border: 1px solid var(--ink-100);
    border-radius: 6px;
    padding: 7px 10px;
    font-size: 13px;
    color: var(--ink-900);
    background: var(--surface);
    font-family: inherit;
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
}
.field-row-body .field-body-full { grid-column: 1 / -1; }
.field-row-body .field-hint {
    font-size: 11px;
    color: var(--ink-500);
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
    margin-top: 2px;
    line-height: 1.4;
}
.field-row-body .field-hint em { font-style: italic; color: var(--ink-700); }
.field-row-body .cond-editor {
    background: #fafafa;
    border: 1px dashed var(--ink-100);
    border-radius: 8px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.field-row-body .cond-editor[data-has-rule="1"] {
    background: #fffbeb;
    border-color: #fde68a;
    border-style: solid;
}
.field-row-body .cond-head {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.field-row-body .cond-label {
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em;
    font-weight: 600; color: var(--ink-500);
}
.field-row-body .cond-clear {
    background: none; border: none; cursor: pointer;
    font-size: 11px; color: var(--ink-500); text-transform: uppercase;
    letter-spacing: 0.06em; padding: 2px 6px; border-radius: 4px;
}
.field-row-body .cond-clear:hover { background: #fef2f2; color: var(--danger, #dc2626); }
.field-row-body .cond-row {
    display: grid;
    grid-template-columns: 1.6fr 1fr 1.4fr;
    gap: 8px;
}
@media (max-width: 680px) {
    .field-row-body .cond-row { grid-template-columns: 1fr; }
}
.field-row-body .scope-toggle .scope-row {
    display: flex; align-items: center; gap: 8px;
    text-transform: none; letter-spacing: normal;
    font-weight: 400; font-size: 13px; color: var(--ink-700);
}
.field-row-body .scope-toggle .scope-row strong {
    font-weight: 600; color: var(--ink-900);
}
.field-row-body .scope-toggle input[type="checkbox"] {
    width: auto; margin: 0;
}

/* ── Options chips editor ──────────────────────────────────────────────
   Replaces the old comma-separated input. Each option is a chip: click
   the label to edit in place, press ✕ to delete, or type in the dashed
   "+ Add option" slot at the end. Used by select/radio/multi-select. */
.opts-wrap .opts-label-row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px; margin-bottom: 6px;
}
.opts-wrap .opts-label-text {
    font-size: 11px;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
.opts-wrap .opts-hint {
    font-size: 11px;
    color: var(--ink-500);
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
}
.opts-chips {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 8px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    background: var(--surface);
    min-height: 44px;
    align-items: center;
}
.opts-chips .opts-parent-switch {
    flex: 0 0 100%;
    display: flex; align-items: center; gap: 8px;
    padding: 4px 6px 8px;
    border-bottom: 1px dashed var(--ink-100);
    margin-bottom: 4px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-500);
}
.opts-chips .opts-parent-switch select {
    font-size: 12px; padding: 4px 8px;
    border: 1px solid var(--ink-100);
    border-radius: 6px;
    background: #fff; color: var(--ink-900);
    text-transform: none; letter-spacing: normal;
    font-weight: 500;
}
.opts-chips .opts-parent-empty {
    font-style: italic; color: #92400e;
    text-transform: none; letter-spacing: normal;
}
.opts-chip-badge {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 10px;
    background: #f3f4f6;
    color: var(--ink-500);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
}
.opts-chip {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 4px 4px 10px;
    background: #eef2ff;
    border: 1px solid #c7d2fe;
    color: var(--ink-900);
    border-radius: 999px;
    font-size: 12px; font-weight: 500;
    font-family: inherit;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
    max-width: 100%;
}
.opts-chip:hover { border-color: var(--accent); }
.opts-chip.editing {
    background: #fff;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.opts-chip-label {
    cursor: text;
    padding: 2px 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    max-width: 200px;
}
.opts-chip > input {
    border: none !important;
    outline: none !important;
    background: transparent !important;
    padding: 2px 2px !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    color: var(--ink-900) !important;
    min-width: 60px;
    width: 140px;
    font-family: inherit;
    text-transform: none;
    letter-spacing: normal;
}
.opts-chip-x {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 50%;
    background: transparent;
    color: var(--ink-500);
    border: none;
    cursor: pointer;
    font-size: 11px;
    line-height: 1;
    padding: 0;
    flex-shrink: 0;
    transition: background 0.12s, color 0.12s;
}
.opts-chip-x:hover { background: rgba(239, 68, 68, 0.12); color: var(--danger, #dc2626); }
.opts-chip-add {
    background: transparent;
    border: 1px dashed #cbd5e1;
    color: var(--ink-500);
    padding: 2px 8px;
}
.opts-chip-add:hover { border-color: var(--accent); }
.opts-chip-add > input {
    width: 130px;
    font-weight: 400 !important;
    color: var(--ink-700) !important;
}
.opts-chip-add > input::placeholder { color: var(--ink-500); }

/* ── Required toggle ───────────────────────────────────────────────────── */
.toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px; color: var(--ink-700); }
.toggle input { display: none; }
.toggle-switch {
    width: 30px; height: 18px; background: #cbd5e1; border-radius: 999px;
    position: relative; transition: background 0.15s;
    flex-shrink: 0;
}
.toggle-switch::after {
    content: ''; position: absolute;
    top: 2px; left: 2px;
    width: 14px; height: 14px;
    background: #fff; border-radius: 50%;
    transition: transform 0.15s;
    box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
.toggle input:checked + .toggle-switch { background: var(--accent); }
.toggle input:checked + .toggle-switch::after { transform: translateX(12px); }
.toggle-label { user-select: none; }

/* ── Price input + section select ──────────────────────────────────────── */
.price-input {
    display: inline-flex; align-items: center;
    background: var(--surface); border: 1px solid var(--ink-100);
    border-radius: 6px; overflow: hidden; width: 110px;
}
.price-symbol { padding: 0 6px 0 8px; color: var(--ink-500); font-size: 13px; }
.price-input input { border: none !important; outline: none; width: 100%; padding: 6px 8px 6px 0 !important; }
.section-select { white-space: nowrap; }

/* ── Chat chips + typing dots ──────────────────────────────────────────── */
.chat-msg.compact .chat-msg-bubble { padding: 8px 12px; font-size: 13px; }
.chat-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 4px; }
.chat-chip {
    border: 1px solid var(--ink-100);
    background: var(--surface);
    color: var(--ink-700);
    font-size: 12px; padding: 6px 12px;
    border-radius: 999px; cursor: pointer;
    transition: border 0.15s, background 0.15s;
    font-family: inherit;
}
.chat-chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

.chat-msg.typing .chat-msg-bubble {
    letter-spacing: 6px; font-size: 18px; padding: 8px 14px; animation: typing-pulse 1s infinite;
}
@keyframes typing-pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

.chat-input button {
    border: none; background: var(--ink-900); color: #fff;
    padding: 0 12px; border-radius: var(--radius-md);
    font-weight: 500; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    min-width: 44px;
}

/* Add-field flash highlight — applies to tickets (.builder-row) AND
   form field rows (.field-row). Fires on add-button clicks + after any
   chat-driven edit via flashRowsInList() in build.html. Triple-pulse
   so a collapsed-then-opened section's expansion animation doesn't eat
   the flash before the organizer sees it. */
.builder-row.flash-new,
.field-row.flash-new { animation: flash-glow 2s ease-out; }
@keyframes flash-glow {
    0%   { box-shadow: 0 0 0 0   rgba(79, 70, 229, 0.55); background: #eef2ff; }
    25%  { box-shadow: 0 0 0 10px rgba(79, 70, 229, 0.32); background: #e0e7ff; }
    55%  { box-shadow: 0 0 0 3px  rgba(79, 70, 229, 0.22); background: #eef2ff; }
    80%  { box-shadow: 0 0 0 12px rgba(79, 70, 229, 0.12); background: #f3f4ff; }
    100% { box-shadow: 0 0 0 0   rgba(79, 70, 229, 0);    background: transparent; }
}

/* ─── Plan live form preview (right pane) ────────────────────────────────
   Mirrors the /v3/embed render so the organizer sees exactly what
   attendees will see. Reloads on every chat reply; on Continue the
   final state is baked in and /build takes over. */
.plan-preview {
    background: var(--ink-900);
    border-left: 1px solid var(--ink-100);
    display: flex;
    flex-direction: column;
    height: 100%;
    min-width: 0;
    min-height: 0;
}
.plan-preview-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 20px;
    color: #fff;
    background: var(--ink-900);
    border-bottom: 1px solid rgba(255,255,255,0.08);
    flex-shrink: 0;
}
.plan-preview-title {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
}
.plan-preview-hint {
    font-size: 12px;
    color: rgba(255,255,255,0.55);
}
.plan-preview-stage {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 20px;
    background:
        radial-gradient(circle at 30% 20%, rgba(79, 70, 229, 0.12), transparent 60%),
        var(--ink-900);
}
.plan-preview-frame {
    width: 100%;
    max-width: 520px;
    height: 100%;
    background: #fff;
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 22px 60px rgba(0,0,0,0.35), 0 1px 0 rgba(255,255,255,0.04);
}
.plan-preview-iframe {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}
.plan-preview-foot {
    padding: 10px 20px 14px;
    font-size: 11.5px;
    color: rgba(255,255,255,0.55);
    text-align: center;
    flex-shrink: 0;
}

/* ─── /publish embed-hero card ───────────────────────────────────────────
   The embed snippet is the primary artifact — this card leads the
   Publish screen. Hosted landing URL is demoted to a secondary card
   below ("Hosted landing page — most organizers embed above instead"). */
.embed-hero-card {
    order: -1;  /* pin to top of publish-grid by default */
    border: 1px solid var(--ink-100);
    box-shadow: var(--shadow-md);
    padding: 28px;
}

/* When a paid event hasn't set up payments yet, the payment card leapfrogs
   the embed-hero card — "do this first" visual priority. order:-2 beats
   embed-hero's -1. The amber outline + soft glow makes it unmissable. */
.publish-card.gate-first {
    order: -2;
    border: 2px solid #f59e0b;
    box-shadow: 0 0 0 6px rgba(245, 158, 11, 0.08), var(--shadow-md);
    background: linear-gradient(180deg, #fffbeb, #fff);
}

/* Pay-required validation banner — renders full-width under the
   manage header on every manage page when the event has paid tickets
   but no verified payment config (suppressed on /payments itself).
   Sits outside .manage-layout so it spans the whole viewport; we
   apply horizontal margins here to match the header's padding. */
.pay-required-banner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    background: #fffbeb;
    border: 1.5px solid #fcd34d;
    border-radius: 14px;
    padding: 16px 20px;
    margin: 16px 22px 0;
    box-shadow: 0 4px 16px -8px rgba(245, 158, 11, 0.25);
}
@media (max-width: 780px) {
    .pay-required-banner { margin: 12px 16px 0; flex-direction: column; align-items: stretch; }
}
.pay-required-banner-left {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    flex: 1;
    min-width: 0;
}
.pay-required-dot {
    width: 10px; height: 10px;
    border-radius: 999px;
    background: #f59e0b;
    flex-shrink: 0;
    margin-top: 7px;
    box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.2);
    animation: pay-required-pulse 2s ease-in-out infinite;
}
@keyframes pay-required-pulse {
    0%, 100% { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.20); }
    50%      { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0.10); }
}
.pay-required-banner strong {
    display: block;
    color: #92400e;
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 2px;
}
.pay-required-hint {
    display: block;
    color: #78350f;
    font-size: 13px;
    line-height: 1.5;
}
.pay-required-cta {
    flex-shrink: 0;
    padding: 10px 18px !important;
    font-size: 13px !important;
    font-weight: 600;
    white-space: nowrap;
    background: #f59e0b !important;
    border-color: #f59e0b !important;
}
.pay-required-cta:hover { background: #d97706 !important; border-color: #d97706 !important; }

/* Sandbox-live chip — compact pill docked right-top of the manage
   content area. Status indicator ("you're in test mode"), not an
   emergency alert: amber fill + pulsing dot + short "Test mode / Fix
   →" copy, long-form consequence in the title= tooltip. The whole
   pill is the link so the full surface is clickable. Amber (not red)
   because being in sandbox is a heads-up worth noticing, not a broken
   state — the old red banner read as "something is on fire" and ate
   half the viewport on /emails and /payments. */
.sandbox-live-chip-row {
    display: flex;
    justify-content: flex-end;
    margin: 0 22px 10px;
}
.sandbox-live-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-radius: 999px;
    padding: 4px 10px 4px 9px;
    font-size: 11.5px;
    font-weight: 500;
    color: #78350f;
    text-decoration: none;
    /* Default state = muted (lives here after the 4s timeout).
       Dimmed so it reads as ambient status, not an alert. */
    opacity: 0.55;
    transition: background 180ms, border-color 180ms, opacity 600ms ease;
}
/* `.is-fresh` is set by the partial's JS on render and stripped after
   4s. Full-opacity window = the notice moment; after that the chip
   fades into passive awareness without re-flowing the layout. */
.sandbox-live-chip.is-fresh { opacity: 1; }
/* Hover always restores full opacity so the affordance survives the
   mute — organiser can still click through to fix without waiting. */
.sandbox-live-chip:hover { background: #fef3c7; border-color: #fcd34d; opacity: 1; }
.sandbox-live-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #f59e0b;
    flex-shrink: 0;
    animation: sandbox-live-pulse 1.8s ease-in-out infinite;
}
@keyframes sandbox-live-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.45; }
}
.sandbox-live-label { color: #92400e; }
.sandbox-live-fix {
    color: #92400e;
    font-weight: 600;
    padding-left: 6px;
    border-left: 1px solid #fde68a;
    margin-left: 2px;
}
@media (max-width: 780px) {
    .sandbox-live-chip-row { margin: 0 16px 8px; }
}
.embed-hero-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 18px;
}
.embed-hero-head h2 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 28px;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--ink-900);
}
.embed-block-hero {
    background: var(--ink-900);
    color: #e7e9f0;
    font-family: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 12.5px;
    line-height: 1.55;
    padding: 16px 18px;
    border-radius: 10px;
    white-space: pre-wrap;
    word-break: break-word;
    margin-bottom: 18px;
}
.embed-preview-row {
    border-top: 1px solid var(--ink-100);
    padding-top: 18px;
}
.publish-previews-single { grid-template-columns: 1fr !important; max-width: none; }

/* ─── Embed delivery-mode tabs — Inline vs Button popup ─────────────────
   Two large radio-style tabs above the snippet block on Publish. Clicking
   one switches which snippet + preview shows (and which is copied). Kept
   visually chunky so the choice reads as a real product decision, not a
   stylistic toggle. */
.embed-mode-tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 18px;
}
.embed-mode-tab {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    background: var(--surface);
    border: 1.5px solid var(--ink-100);
    border-radius: 12px;
    text-align: left;
    cursor: pointer;
    font: inherit;
    color: var(--ink-700);
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.embed-mode-tab:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--ink-900);
}
.embed-mode-tab.active {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--ink-900);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.12);
}
.embed-mode-glyph {
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: 10px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    color: var(--ink-700);
    flex-shrink: 0;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.embed-mode-tab.active .embed-mode-glyph {
    background: #fff;
    border-color: var(--accent);
    color: var(--accent);
}
.embed-mode-label {
    display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.embed-mode-label strong {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-900);
    letter-spacing: -0.005em;
}
.embed-mode-label small {
    font-size: 12.5px;
    color: var(--ink-500);
    font-weight: 400;
}
.embed-mode-desc {
    font-size: 13px;
    color: var(--ink-500);
    line-height: 1.55;
    margin: 12px 0 18px;
}
.embed-mode-desc code {
    background: #f3f4f6;
    border: 1px solid var(--ink-100);
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 11.5px;
    color: var(--ink-900);
    font-family: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace;
}

/* "Try it on this page" demo row in the popup panel. Live button wired
   to the same widget.js that ships in the snippet — so the organizer
   actually sees the popup modal before they paste the code. */
.embed-try {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 18px 20px;
    background: linear-gradient(180deg, #fafaff, #fff);
    border: 1px dashed #c7d2fe;
    border-radius: 12px;
    margin-top: 6px;
}
.embed-try-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-700);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.embed-try-link { margin-left: auto; }

@media (max-width: 640px) {
    .embed-mode-tabs { grid-template-columns: 1fr; }
    .embed-try { flex-wrap: wrap; }
    .embed-try-link { margin-left: 0; width: 100%; }
}

/* ─── /build "ready to embed" strip ──────────────────────────────────────
   Sits between the nav and the 3-pane build layout. Compact, declarative.
   The actual embed snippet + copy action live on /v3/studio/{id}/publish. */
.form-ready-strip {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 22px;
    background: linear-gradient(90deg, var(--accent-soft), rgba(238, 242, 255, 0.4));
    border-bottom: 1px solid var(--ink-100);
    font-size: 13px;
    color: var(--ink-700);
    flex-shrink: 0;
}
.frs-dot {
    width: 8px; height: 8px;
    border-radius: 999px;
    background: var(--accent);
    box-shadow: 0 0 0 4px rgba(79, 70, 229, 0.18);
    flex-shrink: 0;
}
.frs-title { font-weight: 600; color: var(--ink-900); }
.frs-hint { color: var(--ink-500); }

body.studio-body.no-page-scroll > .form-ready-strip { flex-shrink: 0; }

/* ─── Plan questionnaire — Claude-Design-inspired chip layout ────────────
   Used by the right pane of /v3/studio/{id}/plan (plan.html).
   Single-select: clicking a chip fills it; clicking again falls back to
   "Decide for me". Multi-select: toggle any number; escape via "Other…".
   Freeform: plain text input, blank = use default.                       */
.plan-questions {
    background: var(--canvas);
    min-height: 0;
    min-width: 0;
    /* Explicit full-row height — without this, the grid row auto-sizes
       to content, the flex column has no upper bound, and the inner
       scroll container never triggers its scrollbar. Mirrors .plan-chat. */
    height: 100%;
    overflow: hidden;
    border-right: 1px solid var(--ink-100);
    display: flex;
    flex-direction: column;
}
.plan-questions-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 40px 40px 40px;
}
.plan-questions-inner { max-width: 560px; margin: 0 auto; }

/* ── Event-requirements checklist on /plan ────────────────────────
   Systemic ask layer: a grouped checklist that surfaces what's
   still needed before the event can practically go live. Sits below
   the Claude-Design questionnaire so the organiser confirms inline
   before clicking Continue. Rows auto-save via PATCH — no submit,
   no navigation loss. */
.plan-req {
    margin: 40px 0 8px;
    padding: 20px 22px 16px;
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    box-shadow: 0 14px 32px -26px rgba(11, 15, 25, 0.15);
}
.plan-req[data-ready="true"] {
    border-color: #a7f3d0;
    box-shadow: 0 14px 32px -26px rgba(16, 185, 129, 0.25);
}
.plan-req-header { margin-bottom: 14px; }
.plan-req-header h2 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 22px;
    margin: 0 0 4px;
    color: var(--ink-900);
    letter-spacing: -0.005em;
}
.plan-req-progress {
    margin: 0;
    font-size: 13px;
    color: var(--ink-500);
}
.plan-req-group { margin-top: 18px; }
.plan-req-group:first-of-type { margin-top: 6px; }
.plan-req-group-label {
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-500);
    margin-bottom: 10px;
}
.plan-req-row {
    padding: 12px 14px;
    margin-bottom: 10px;
    background: #fafafa;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    transition: border-color 0.12s, background 0.12s;
}
.plan-req-row.status-satisfied {
    background: #f7fffb;
    border-color: #a7f3d0;
}
.plan-req-row.status-missing_required {
    background: #fffbf5;
    border-color: #fde68a;
}
.plan-req-row-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; flex-wrap: wrap;
    margin-bottom: 6px;
}
.plan-req-label {
    font-size: 13.5px; font-weight: 600;
    color: var(--ink-900);
    display: inline-flex; align-items: center; gap: 8px;
}
.plan-req-req {
    font-size: 9.5px; font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 3px;
    background: #fef2f2; color: #991b1b;
}
.plan-req-status-badge {
    font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.04em;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--ink-100);
    color: var(--ink-500);
}
.status-satisfied .plan-req-status-badge { background: #ecfdf5; color: #047857; }
.status-missing_required .plan-req-status-badge { background: #fef3c7; color: #b45309; }
.plan-req-input {
    width: 100%;
    padding: 9px 11px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font: inherit;
    font-size: 13.5px;
    color: var(--ink-900);
    background: #fff;
}
.plan-req-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.plan-req-why {
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--ink-500);
    line-height: 1.5;
}
.plan-req-error {
    margin-top: 6px;
    font-size: 11.5px;
    color: #991b1b;
}
/* Invalid-input visual — fires when the type-aware validator
   (URL etc.) rejects the current value. Red border + soft red
   ring so the row reads as 'fix me' without the row-level
   shake animation reserved for the Continue-pressed case. */
.plan-req-row.is-invalid .plan-req-input {
    border-color: #fecaca;
    background: #fff7f7;
}
.plan-req-row.is-invalid .plan-req-input:focus {
    border-color: #dc2626;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
}

/* Continue-blocked: shake the offending row + flash a red border.
   Triggered when the organiser hits Continue with required fields
   still empty. Honours prefers-reduced-motion by staying still and
   just swapping border colour. */
@keyframes plan-req-shake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-6px); }
    40% { transform: translateX(5px); }
    60% { transform: translateX(-3px); }
    80% { transform: translateX(2px); }
}
.plan-req-shake {
    animation: plan-req-shake 0.45s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
    border-color: #f87171 !important;
    background: #fef2f2 !important;
}
@media (prefers-reduced-motion: reduce) {
    .plan-req-shake { animation: none; }
}

/* Inline summary above the footer that names every still-missing
   required field. Replaces any prior note — the gate handler
   guarantees this element renders at most once at any moment. */
.plan-req-block-note {
    margin: 14px auto 0;
    max-width: 560px;
    padding: 10px 14px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 8px;
    color: #991b1b;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.5;
}

/* ── Floating TOC on /plan ─────────────────────────────────────
   Sticky right-hand mini-nav. Each item is a dot + label; the dot
   fills as you scroll into the matching section (driven by the
   IntersectionObserver in plan.html). Hidden under 1100px because
   the questions column already fills the screen at narrower
   widths and the TOC would crowd it. */
.plan-toc {
    position: fixed;
    top: 50%;
    /* Align with the questions column's right edge instead of being
       pinned 24px from the viewport edge. The plan layout's main
       column maxes out at ~720px and is centred; on a 1440px screen
       the right edge sits around 1080px. clamp() keeps the panel
       hugging that edge across viewport widths so the composition
       reads as a paired column, not a floating outlier. */
    right: clamp(24px, calc((100vw - 720px) / 2 - 232px), 80px);
    transform: translateY(-50%);
    z-index: 40;
    max-height: 70vh;
    overflow-y: auto;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(10px);
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    padding: 14px 14px 12px;
    box-shadow:
        0 1px 2px rgba(15, 23, 42, 0.04),
        0 18px 36px -22px rgba(11, 15, 25, 0.18);
    width: 220px;
    pointer-events: auto;
}
/* Heading row — small uppercase label + a subtle progress bar
   underneath that fills as the active section advances down the
   list. Gives the panel a clear identity ('jump to') and a sense
   of progress without taking real estate. */
.plan-toc-head {
    display: flex; flex-direction: column; gap: 6px;
    padding: 0 4px 10px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--ink-100);
}
.plan-toc-title {
    font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--ink-500);
}
.plan-toc-progress {
    height: 3px; border-radius: 999px;
    background: rgba(11, 15, 25, 0.06);
    position: relative;
    overflow: hidden;
}
.plan-toc-progress::after {
    content: '';
    position: absolute; left: 0; top: 0; bottom: 0;
    width: var(--plan-toc-progress, 0%);
    background: linear-gradient(90deg, #818cf8 0%, #4f46e5 100%);
    border-radius: 999px;
    transition: width 220ms ease;
}
.plan-toc-list {
    list-style: none;
    padding: 0; margin: 0;
    display: flex; flex-direction: column;
    gap: 2px;
}
.plan-toc-item a {
    display: flex; align-items: center; gap: 10px;
    padding: 6px 6px;
    color: var(--ink-500);
    text-decoration: none;
    font-size: 12px;
    line-height: 1.35;
    border-radius: 6px;
    transition: background 0.12s, color 0.12s;
}
.plan-toc-item a:hover {
    color: var(--ink-900);
    background: var(--ink-100);
}
.plan-toc-dot {
    width: 8px; height: 8px;
    border-radius: 999px;
    background: transparent;
    border: 1.5px solid var(--ink-200, #d4d4d8);
    flex-shrink: 0;
    transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
.plan-toc-item a.is-active {
    color: var(--ink-900);
    font-weight: 600;
    background: rgba(79, 70, 229, 0.06);
}
.plan-toc-item a.is-active .plan-toc-dot {
    background: var(--accent);
    border-color: var(--accent);
    transform: scale(1.15);
}
.plan-toc-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
@media (max-width: 1100px) {
    .plan-toc { display: none; }
}


.plan-q-header { margin-bottom: 36px; }
.plan-q-title {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 40px;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--ink-900);
    margin: 0 0 12px;
}
.plan-q-sub {
    font-size: 15px; color: var(--ink-500); line-height: 1.55;
    max-width: 560px; margin: 0;
}
.plan-q-sub em { color: var(--ink-700); font-style: italic; }

.plan-q-section {
    padding: 24px 0;
    border-top: 1px solid var(--ink-100);
}
.plan-q-section h2 {
    font-size: 17px;
    font-weight: 600;
    color: var(--ink-900);
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}
.plan-q-hint {
    font-size: 13px; color: var(--ink-500); margin: 0 0 14px; line-height: 1.5;
}

.plan-q-chips {
    display: flex; flex-wrap: wrap; gap: 8px;
}
.plan-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 14px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 999px;
    font-family: inherit;
    font-size: 13px;
    color: var(--ink-700);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s, box-shadow 0.15s;
}
.plan-chip:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}
.plan-chip.selected {
    border-color: var(--ink-900);
    background: var(--ink-900);
    color: #fff;
    font-weight: 500;
}
.plan-chip.selected:hover {
    border-color: var(--ink-900);
    background: var(--ink-900);
    color: #fff;
}
.plan-chip-escape {
    border-style: dashed;
    color: var(--ink-500);
}
.plan-chip-escape.selected {
    border-style: solid;
    background: var(--ink-900);
    color: #fff;
}
.plan-chip-other {
    color: var(--ink-500);
    border-style: dashed;
}

.plan-q-freeform { margin-top: 4px; }
.plan-q-input {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    color: var(--ink-900);
    background: var(--surface);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.plan-q-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Action bar pinned outside the questionnaire scroll area so it can
   never overlap or bleed under a chip row. Full width of the right
   pane, with the inner row re-centred to the 560px questionnaire grid. */
.plan-q-footer {
    flex: 0 0 auto;
    background: var(--canvas);
    border-top: 1px solid var(--ink-100);
    box-shadow: 0 -8px 20px -14px rgba(15, 23, 42, 0.12);
    padding: 16px 40px;
}
.plan-q-footer-inner {
    max-width: 560px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 14px;
}
.plan-q-progress {
    font-size: 12px;
    color: var(--ink-500);
    margin-right: auto;
}
/* Required-fields counter — sits next to the optional "X of Y answered"
   counter so the organiser can tell whether they're blocked (required
   missing) vs just leaving optional answers on the table. Hidden when
   empty so a form with no required fields doesn't render an empty pill. */
.plan-q-required-count {
    font-size: 12px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 999px;
    background: #fef2f2;
    color: #b91c1c;
    border: 1px solid #fecaca;
}
.plan-q-required-count:empty { display: none; }
.plan-q-required-count.is-complete {
    background: #ecfdf5;
    color: #047857;
    border-color: #a7f3d0;
}
/* Continue button — visibly inactive when the required-fields gate
   would block the click. The click handler still fires (so the existing
   shake-and-scroll feedback still works as a backup), but the button
   reads as not-yet-actionable so the organiser doesn't bounce off
   thinking the button is broken. */
.btn-gradient-forward.is-blocked {
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
    filter: saturate(0.7);
}
.btn-gradient-forward.is-blocked:hover {
    transform: none;
    box-shadow: none;
}

/* Preview frame flash — fires after every chat submit so the organizer's
   eye follows the edit into the iframe even when only the landing page
   changed (no specific builder row to highlight). */
.preview-frame { transition: box-shadow 0.2s ease-out; }
.preview-frame.flash { animation: flash-preview 1.6s ease-out; }
@keyframes flash-preview {
    0%   { box-shadow: 0 0 0 0 rgba(79, 70, 229, 0.55), 0 12px 40px rgba(79, 70, 229, 0.25); }
    30%  { box-shadow: 0 0 0 6px rgba(79, 70, 229, 0.35), 0 18px 48px rgba(79, 70, 229, 0.28); }
    100% { box-shadow: 0 0 0 0 rgba(79, 70, 229, 0), 0 4px 12px rgba(15, 23, 42, 0.08); }
}

.btn-link {
    background: transparent; border: none; color: var(--accent);
    font-size: 12px; cursor: pointer; padding: 4px 8px; border-radius: 4px;
    font-family: inherit;
}
.btn-link:hover { background: var(--accent-soft); }
.mini-link { background: transparent; border: none; color: var(--accent); font-size: 12px; cursor: pointer; padding: 0 4px; text-decoration: none; }
.mini-link:hover { text-decoration: underline; }

/* ── Publish improvements ──────────────────────────────────────────────── */
.payment-choice { position: relative; }
.payment-choice.recommended { border-color: var(--accent); background: linear-gradient(180deg, #fafbff, #fff); }
.payment-choice.recommended.active { border-color: var(--ink-900); }
.payment-choice h3 { margin-top: 4px; }
.choice-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    width: fit-content;
    margin-bottom: 4px;
}
.choice-badge.warning { background: #fef3c7; color: #92400e; }

/* Legacy .provider-label rule retired — the label text was moved into the
   .provider-pill-card grid on /v3/studio/{id}/payments. Retained here as
   a comment so future greps find the history. The new .provider-label
   used by /admin/platform/payments (input.provider-input.provider-label)
   is defined in the admin block later in this stylesheet. */

.publish-note { font-size: 12px; color: var(--ink-500); margin: 12px 0 0; }

.embed-header {
    display: flex; justify-content: space-between; align-items: center;
    margin: 14px 0 6px; font-size: 12px; color: var(--ink-500);
    text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600;
}
.embed-header button { text-transform: none; letter-spacing: normal; font-size: 12px; font-weight: 500; }
.embed-block button { display: none; }  /* relocated to embed-header */

.btn-publish-cta { padding: 14px 24px; font-size: 15px; letter-spacing: 0.01em; }
/* Inside the manage header the Publish CTA shrinks so the nav stays
   flush with the 64px shared height used on /events and /platform. */
.studio-nav .btn-publish-cta { padding: 9px 20px; font-size: 14px; }
.spinner-inline {
    display: inline-block;
    width: 12px; height: 12px;
    border: 2px solid rgba(255,255,255,0.4);
    border-top-color: #fff;
    border-radius: 50%;
    margin-right: 6px;
    animation: spin 0.7s linear infinite;
    vertical-align: -1px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Live banner + share card ──────────────────────────────────────────── */
.live-banner {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    color: var(--ink-700);
    padding: 18px 22px;
    border-radius: var(--radius-lg);
    margin-bottom: 22px;
    box-shadow: var(--shadow-sm);
    transition: background 0.35s, border-color 0.35s, box-shadow 0.35s;
}
.live-banner.is-live {
    background: linear-gradient(135deg, #ecfdf5 0%, #f0fdf4 60%, #fff 100%);
    border-color: #a7f3d0;
    color: #065f46;
    box-shadow: 0 4px 24px rgba(22, 163, 74, 0.08);
}
.live-banner.just-published { animation: banner-in 0.5s cubic-bezier(0.16, 1, 0.3, 1); }
@keyframes banner-in {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}
.live-banner-head { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }
.live-banner-head strong.live-title { font-size: 17px; display: block; color: inherit; }
.live-sub { font-size: 13px; color: var(--ink-500); display: block; margin-top: 2px; }
.live-banner.is-live .live-sub { color: #047857; }
.live-dot {
    width: 10px; height: 10px; border-radius: 50%;
    background: var(--ink-300);
    box-shadow: 0 0 0 4px rgba(156, 163, 175, 0.18);
    flex-shrink: 0;
    transition: background 0.3s, box-shadow 0.3s;
}
.live-banner.is-live .live-dot {
    background: #10b981;
    box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.22);
    animation: live-pulse 1.8s ease-in-out infinite;
}
@keyframes live-pulse {
    0%, 100% { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.22); }
    50% { box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); }
}
.share-grid { display: grid; gap: 10px; }
.share-url-row {
    display: flex; gap: 8px; align-items: center;
    background: var(--surface); border: 1px solid var(--ink-100);
    border-radius: var(--radius-md); padding: 4px 4px 4px 14px;
    transition: border-color 0.3s;
}
.live-banner.is-live .share-url-row { border-color: #d1fae5; }
.share-url-row input {
    flex: 1; border: none; background: transparent;
    font-size: 13px; font-family: 'SF Mono', Menlo, monospace;
    color: var(--ink-700); outline: none;
}
.share-url-row .btn-primary { padding: 8px 16px; font-size: 13px; }
.share-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.share-btn {
    display: inline-flex; align-items: center; gap: 7px;
    border: 1px solid #d1fae5; background: var(--surface);
    padding: 8px 14px; border-radius: 999px;
    font-size: 13px; font-weight: 500; color: var(--ink-700);
    text-decoration: none; transition: transform 0.08s, border 0.15s, color 0.15s;
}
.share-btn:hover { transform: translateY(-1px); border-color: #a7f3d0; color: var(--ink-900); }
.share-btn svg { flex-shrink: 0; }
.share-whatsapp { color: #25D366; }
.share-whatsapp:hover { color: #1ebc59; border-color: #25D366; }
.share-linkedin { color: #0a66c2; }
.share-linkedin:hover { color: #0a66c2; border-color: #0a66c2; }
.share-x { color: #0b0f19; }
.share-x:hover { border-color: #0b0f19; }

/* ── Confetti ──────────────────────────────────────────────────────────── */
.confetti {
    position: fixed;
    top: -12px;
    width: 8px; height: 14px;
    border-radius: 2px;
    animation: confetti-fall linear forwards;
    z-index: 9999;
    pointer-events: none;
}
@keyframes confetti-fall {
    0% { transform: translateY(-10vh) rotateZ(0deg); opacity: 1; }
    100% { transform: translateY(105vh) rotateZ(720deg); opacity: 0.8; }
}

/* ── Responsive ladder ────────────────────────────────────────────────
   Five tiers, ordered widest-first. Each tier ONLY adjusts what the
   previous one didn't get right at this width — no full restyles.

     ≥1340  → flagship desktop (defaults above)
     ≤1340  → 1280px laptops; slim chat + TOC, smaller hero title
     ≤1200  → older laptops; chat tightens further, side cards stack
     ≤1024  → iPad landscape; drop the TOC, widen form to fill,
              tighter form padding
     ≤900   → iPad portrait / small tablet; chat collapses to a 36px
              rail (icon-only); main goes full width
     ≤780   → phones; chat hidden, single column, full-bleed form */
@media (max-width: 1340px) {
    .plan-layout { --plan-chat-w-max: 340px; --plan-chat-w-min: 260px; }
    .plan-layout { --plan-chat-w: min(var(--plan-chat-w), 340px); }
    .plan-toc { width: 220px; }
    .plan-q-section { padding: 20px 0; }
    .plan-main { padding: 32px 28px 80px; }
    .plan-q-title { font-size: 32px; }
}
@media (max-width: 1200px) {
    .build-layout { --chat-w-max: 380px; }
    .build-layout { --chat-w: min(var(--chat-w), 380px); }
    .build-pane.builder { display: none; }
    .plan-layout { --plan-chat-w-max: 320px; --plan-chat-w-min: 240px; }
    .plan-layout { --plan-chat-w: min(var(--plan-chat-w), 320px); }
    .plan-toc { width: 200px; }
    .plan-main { padding: 28px 24px 72px; }
    .plan-q-title { font-size: 30px; }
    .plan-grid { grid-template-columns: 1fr; }
    .plan-card-wide { grid-column: span 1; }
    .publish-grid { grid-template-columns: 1fr; }
    .publish-card-wide { grid-column: span 1; }
    .publish-previews { grid-template-columns: 1fr; }
}
@media (max-width: 1024px) {
    /* iPad landscape (1024×768). The TOC is the first to go — its
       value-density drops fast at this width and reclaiming 200px
       lets the questions read like a native form again. Chat stays
       so the AI loop still works on tablets without pulling out a
       laptop. */
    .plan-toc { display: none; }
    .plan-layout { --plan-chat-w-max: 300px; --plan-chat-w-min: 220px; }
    .plan-layout { --plan-chat-w: min(var(--plan-chat-w), 300px); }
    .plan-main { padding: 24px 20px 64px; max-width: none; }
    .plan-q-title { font-size: 28px; }
    .plan-q-section { padding: 16px 0; }
}
@media (max-width: 900px) {
    /* iPad portrait (768×1024) + small Android tablets. Chat compresses
       to an icon rail; tap to expand inline. The full-bleed form is
       the priority — organisers on tablets are usually triaging an
       event mid-meeting, not chatting with the AI. */
    .plan-layout { --plan-chat-w: 0px; }
    .plan-layout { grid-template-columns: 0 1fr; }
    .plan-chat { display: none; }
    .chat-resizer { display: none; }
    .plan-main { padding: 20px 18px 60px; }
}
@media (max-width: 780px) {
    /* Phone — single column, no chat sidebar, full-bleed form.
       (Already most of the heavy lifting; this stanza just keeps the
       legacy build screen + studio nav in step.) */
    .build-layout { grid-template-columns: 1fr; }
    .build-pane.chat { display: none; }
    .plan-layout { grid-template-columns: 1fr; }
    .plan-chat { display: none; }
    .studio-nav-steps { display: none; }
    .plan-main { padding: 18px 14px 52px; }
    .plan-q-title { font-size: 24px; }
    .plan-q-section { padding: 14px 0; }
    /* Footer Continue/Skip — pin bottom on phones so it's reachable
       without thumb-stretching past a long form. */
    .plan-q-footer-inner { gap: 8px; padding: 12px 14px; }
}

/* ─── Registrations screen (Phase 8 — who's registered) ──────────────── */
.registrations-main { max-width: 1200px; margin: 0 auto; padding: 40px 24px 80px; }
.registrations-hero { margin-bottom: 28px; }
.registrations-hero h1 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 42px;
    letter-spacing: -0.02em;
    margin: 0 0 6px;
}
.registrations-hero p { color: var(--ink-500); margin: 0; font-size: 15px; }

.metric-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 28px;
}
.metric-card {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    box-shadow: var(--shadow-sm);
}
.metric-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-500);
    font-weight: 600;
}
.metric-value {
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 32px;
    font-weight: 400;
    letter-spacing: -0.01em;
    color: var(--ink-900);
    line-height: 1.1;
}
.metric-sub { font-size: 12px; color: var(--ink-500); }

@media (max-width: 900px) {
    .metric-grid { grid-template-columns: repeat(2, 1fr); }
}

.registrations-filters {
    display: flex;
    align-items: flex-end;
    gap: 16px;
    margin-bottom: 18px;
    padding: 14px 18px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 12px;
}
.registrations-filters .filter-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.registrations-filters label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-500);
    font-weight: 600;
}
.registrations-filters select {
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 14px;
    font-family: inherit;
    background: var(--surface);
    min-width: 180px;
    cursor: pointer;
}
.registrations-filters select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.registrations-filters .filter-spacer { flex: 1; }

.registrations-table-wrap {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    overflow: hidden;
}
.registrations-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}
.registrations-table th {
    text-align: left;
    padding: 12px 16px;
    background: #f9fafb;
    color: var(--ink-500);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-bottom: 1px solid var(--ink-100);
}
.registrations-table th.num { text-align: right; }
.registrations-table td {
    padding: 14px 16px;
    border-bottom: 1px solid #f3f4f6;
    color: var(--ink-700);
    vertical-align: middle;
}
.registrations-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.registrations-table td.mono { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 13px; color: var(--ink-500); }
.registrations-table td.ellipsis {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.registrations-table .reg-name { font-weight: 600; color: var(--ink-900); }
.registrations-table tr:last-child td { border-bottom: 0; }

.reg-status {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.reg-status-confirmed,
.reg-status-paid { background: #d1fae5; color: #065f46; }
.reg-status-pending { background: #fef3c7; color: #92400e; }
.reg-status-pending_payment { background: #ffedd5; color: #9a3412; }
.reg-status-cancelled { background: #fee2e2; color: #991b1b; }
.reg-status-refunded { background: #e0e7ff; color: #3730a3; }

/* In-cart partial registrations — distinct from sandbox so the
   organiser can scan the table and tell "no money has changed
   hands yet" apart from a sandbox simulation. Slightly cooler
   tint than sandbox amber. */
.reg-row-partial td { background: #fff7ed; }
.registrations-table .reg-row-partial td s {
    color: var(--ink-500);
}

/* Sandbox rows come from /admin/platform/payments' per-provider
   sandbox toggle. Visually dim them and tag each row so the organiser
   never confuses a simulated order for a real one; the row-level
   metrics strip above already excludes them from revenue + paid count. */
.reg-row-sandbox td { background: #fffbeb; }
.reg-sandbox-tag {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background: #fef3c7;
    color: #92400e;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.registrations-table .reg-row-sandbox td s {
    color: var(--ink-500);
}

.registrations-note {
    text-align: center;
    color: var(--ink-500);
    font-size: 13px;
    padding: 16px;
    border-top: 1px solid var(--ink-100);
    margin: 0;
}

.registrations-empty {
    text-align: center;
    padding: 60px 24px;
    background: var(--surface);
    border: 1px dashed var(--ink-100);
    border-radius: 14px;
}
.registrations-empty h2 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 28px;
    margin: 0 0 8px;
    color: var(--ink-900);
}
.registrations-empty p {
    color: var(--ink-500);
    font-size: 15px;
    margin: 0 0 20px;
    max-width: 460px;
    margin-left: auto;
    margin-right: auto;
}

/* Per-row action button (Refund, etc.) — quiet by default, accent on hover */
.row-actions { text-align: right; }
.btn-row-action {
    border: 1px solid var(--ink-100);
    background: var(--surface);
    color: var(--ink-700);
    padding: 6px 14px;
    border-radius: 8px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.btn-row-action:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}

/* ─── Refund policy row on /publish ────────────────────────────────── */
.refund-policy-row {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 20px;
    padding: 14px 16px;
    background: #f9fafb;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
}
.refund-policy-head { display: flex; flex-direction: column; gap: 2px; }
.refund-policy-label { font-size: 13px; font-weight: 600; color: var(--ink-900); }
.refund-policy-hint { font-size: 12px; color: var(--ink-500); }
.refund-policy-select {
    margin-left: auto;
    min-width: 240px;
    padding: 8px 12px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-size: 13px;
    font-family: inherit;
    background: var(--surface);
    cursor: pointer;
}
.refund-policy-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.refund-policy-status { font-size: 12px; color: var(--ink-500); min-width: 90px; }
.refund-policy-status.saving { color: var(--ink-500); }
.refund-policy-status.ok     { color: #16a34a; }
.refund-policy-status.fail   { color: #dc2626; }

/* ─── Refund confirm drawer (slides from right on /registrations) ──── */
.refund-backdrop {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(2px);
    z-index: 90;
    opacity: 0;
    transition: opacity 0.18s ease-out;
}
.refund-backdrop.open { opacity: 1; }
.refund-drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: 440px;
    max-width: 100vw;
    background: var(--surface);
    box-shadow: -16px 0 48px rgba(15, 23, 42, 0.15);
    z-index: 100;
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.22s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.refund-drawer.open { transform: translateX(0); }
.refund-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px;
    border-bottom: 1px solid var(--ink-100);
}
.refund-drawer-head h3 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 24px;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--ink-900);
}
.refund-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.refund-order-summary {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 14px 16px;
    background: #f9fafb;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
}
.refund-field { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.refund-field-label { font-size: 12px; color: var(--ink-500); font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; }
.refund-field-value { font-size: 14px; color: var(--ink-900); font-weight: 500; }
.refund-field-value.mono { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 13px; }
.refund-amount-row label,
.refund-reason-row label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-900);
    margin-bottom: 8px;
}
.refund-amount-input {
    display: flex;
    align-items: center;
    border: 1.5px solid var(--ink-100);
    border-radius: 10px;
    overflow: hidden;
    background: var(--surface);
    transition: border-color 0.15s;
}
.refund-amount-input:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.refund-amount-currency {
    padding: 10px 14px;
    background: #f3f4f6;
    color: var(--ink-500);
    font-size: 13px;
    font-weight: 600;
    border-right: 1px solid var(--ink-100);
}
.refund-amount-input input {
    flex: 1;
    border: 0;
    padding: 10px 14px;
    font-family: inherit;
    font-size: 16px;
    font-variant-numeric: tabular-nums;
    background: transparent;
    outline: none;
    color: var(--ink-900);
}
.refund-amount-hint {
    font-size: 12px;
    color: var(--ink-500);
    margin: 8px 0 0;
    line-height: 1.5;
}
.refund-reason-row textarea {
    width: 100%;
    border: 1.5px solid var(--ink-100);
    border-radius: 10px;
    padding: 10px 14px;
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    resize: vertical;
    min-height: 80px;
    background: var(--surface);
    color: var(--ink-900);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.refund-reason-row textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.refund-error {
    padding: 10px 14px;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 8px;
    color: #991b1b;
    font-size: 13px;
    line-height: 1.5;
}
.refund-drawer-foot {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding: 16px 24px;
    border-top: 1px solid var(--ink-100);
    background: #f9fafb;
}

/* ─── Organizer identity card on /publish ───────────────────────────── */
#organizer-identity-card details { display: block; }
#organizer-identity-card summary {
    display: block;
    list-style: none;
    cursor: pointer;
    padding: 0;
}
#organizer-identity-card summary::-webkit-details-marker { display: none; }
#organizer-identity-card summary::marker { display: none; }
.organizer-identity-head {
    position: relative;
    padding-right: 28px;
}
.organizer-identity-head::after {
    content: "›";
    position: absolute;
    right: 0;
    top: 50%;
    transform: translateY(-50%) rotate(90deg);
    font-size: 24px;
    color: var(--ink-300);
    transition: transform 0.15s;
}
#organizer-identity-card details[open] .organizer-identity-head::after {
    transform: translateY(-50%) rotate(270deg);
}
.organizer-identity-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--ink-100);
}
.organizer-identity-grid label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-900);
}
.organizer-identity-grid label.field-full { grid-column: 1 / -1; }
.organizer-identity-grid label.field-checkbox {
    flex-direction: row;
    align-items: flex-start;
    gap: 10px;
    font-weight: 400;
    font-size: 13px;
    color: var(--ink-700);
    line-height: 1.5;
    padding: 10px 14px;
    background: #f9fafb;
    border-radius: 8px;
}
.organizer-identity-grid label.field-checkbox input { margin-top: 2px; }
.organizer-identity-grid input[type="text"],
.organizer-identity-grid input[type="email"],
.organizer-identity-grid input[type="tel"],
.organizer-identity-grid input[type="url"],
.organizer-identity-grid input[type="number"],
.organizer-identity-grid select,
.organizer-identity-grid textarea {
    border: 1.5px solid var(--ink-100);
    border-radius: 8px;
    padding: 10px 12px;
    font-family: inherit;
    font-size: 14px;
    background: var(--surface);
    color: var(--ink-900);
    transition: border-color 0.15s, box-shadow 0.15s;
    -webkit-appearance: none;
    appearance: none;
}
.organizer-identity-grid select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 34px;
}
.organizer-identity-grid input:focus,
.organizer-identity-grid textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.organizer-identity-grid textarea { resize: vertical; min-height: 60px; line-height: 1.5; }
.organizer-save-status {
    display: inline-block;
    margin-top: 12px;
    font-size: 12px;
    color: var(--ink-500);
    min-height: 18px;
}
.organizer-save-status.saving { color: var(--ink-500); }
.organizer-save-status.ok { color: #16a34a; }
.organizer-save-status.fail { color: #dc2626; }

/* ─── Compact payment status strip on /publish ────────────────────────
   Replaces the big all-in-one yellow setup card. Full config lives on
   /v3/studio/{id}/payments — this row is just the status readout + a
   clear CTA to go manage it. */
.payment-status-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 20px 22px !important;
}
.payment-status-strip.unverified {
    border: 2px solid #f59e0b;
    box-shadow: 0 0 0 6px rgba(245, 158, 11, 0.08), var(--shadow-md);
    background: linear-gradient(180deg, #fffbeb, #fff);
}
.payment-status-left {
    display: flex;
    align-items: center;
    gap: 16px;
    flex: 1;
    min-width: 0;
}
.payment-status-title {
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--ink-900);
    margin-bottom: 2px;
}
.payment-status-desc {
    display: block;
    font-size: 13px;
    color: var(--ink-500);
    line-height: 1.45;
}
.payment-status-cta {
    flex-shrink: 0;
    padding: 10px 18px !important;
    font-size: 13px !important;
    font-weight: 600;
    white-space: nowrap;
}

/* ─── Dedicated /payments screen ──────────────────────────────────────── */
.payments-main {
    max-width: 920px;
    margin: 0 auto;
    padding: 40px 24px 80px;
}
.payments-hero { margin-bottom: 36px; }
.payments-hero h1 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 48px;
    letter-spacing: -0.02em;
    margin: 0 0 8px;
    color: var(--ink-900);
}
.payments-sub {
    font-size: 15px;
    color: var(--ink-500);
    line-height: 1.55;
    margin: 0 0 18px;
    max-width: 620px;
}
.payments-status {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    margin-top: 12px;
}
.payments-status-badge {
    font-weight: 700;
    font-size: 13px;
    padding: 6px 12px;
    border-radius: 999px;
    white-space: nowrap;
}
.payments-status-badge.status-ok {
    background: #d1fae5;
    color: #065f46;
}
.payments-status-badge.status-todo {
    background: #fee2e2;
    color: #991b1b;
}
.payments-status-desc {
    color: var(--ink-500);
    font-size: 13px;
    line-height: 1.5;
}

/* Tabs that split the Payments page into Setup vs Receipts — keeps the
   screen one-viewport-scannable. Sits between the hero status strip
   and the section cards. Only renders for paid events (free events
   have one surface, so the tab bar would be noise). */
.payments-tabs {
    display: flex;
    gap: 4px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--ink-100);
    padding-bottom: 0;
}
.payments-tab {
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 10px 18px 12px;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-500);
    cursor: pointer;
    margin-bottom: -1px;
    transition: color 0.12s, border-color 0.12s;
}
.payments-tab:hover { color: var(--ink-900); }
.payments-tab.active {
    color: var(--ink-900);
    border-bottom-color: var(--accent);
}
.payments-tab-panel { display: block; }
.payments-tab-panel[hidden] { display: none; }

.payments-section {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    padding: 28px;
    margin-bottom: 18px;
    box-shadow: var(--shadow-sm);
}
.payments-section-head { margin-bottom: 18px; }
.payments-section-head h2 {
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 6px;
    color: var(--ink-900);
}
.payments-section-head p {
    font-size: 13.5px;
    color: var(--ink-500);
    line-height: 1.5;
    margin: 0;
}

/* Fee illustration — appears inside the "How should payments flow?"
   section when e2m_managed is the selected mode. Two stacked blocks:
   a headline fee list and a worked example table so the organizer can
   see the percentage AND the net payout on a concrete ticket price. */
.e2m-fees-panel {
    margin-top: 20px;
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    background: linear-gradient(180deg, #fafbff, #fff);
    padding: 20px 22px;
}
.e2m-fees-head {
    margin-bottom: 14px;
}
.e2m-fees-head h3 {
    font-size: 15px;
    font-weight: 700;
    color: var(--ink-900);
    margin: 0 0 4px;
    letter-spacing: -0.005em;
}
.e2m-fees-head p {
    font-size: 12.5px;
    color: var(--ink-500);
    line-height: 1.5;
    margin: 0;
}
.e2m-fees-list {
    list-style: none;
    padding: 0;
    margin: 0 0 18px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 14px;
}
.e2m-fees-list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid #eef0f6;
    font-size: 13px;
}
.e2m-fees-list li:last-child,
.e2m-fees-list li:nth-last-child(2):nth-child(odd) {
    border-bottom: none;
}
.e2m-fee-label { color: var(--ink-500); }
.e2m-fee-value { color: var(--ink-900); font-weight: 600; text-align: right; }

.e2m-fees-example {
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    padding: 14px 16px;
}
.e2m-fees-example-title {
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 8px;
}
.e2m-fees-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}
.e2m-fees-table td {
    padding: 6px 0;
    color: var(--ink-700);
}
.e2m-fees-table td:last-child {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--ink-900);
}
.e2m-fees-table tr.neg td:last-child { color: #b91c1c; }
.e2m-fees-table tr.net td {
    border-top: 1px solid var(--ink-100);
    padding-top: 10px;
    font-size: 14px;
    color: var(--ink-900);
}
.e2m-fees-note {
    margin: 12px 0 0;
    font-size: 12px;
    color: var(--ink-500);
    line-height: 1.55;
}
@media (max-width: 640px) {
    .e2m-fees-list { grid-template-columns: 1fr; }
}

/* Provider pill grid — wider cards with an extra subtitle line */
.provider-pill-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 10px;
}
.provider-pill-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: flex-start;
    border: 1.5px solid var(--ink-100);
    background: var(--surface);
    padding: 14px 18px;
    border-radius: 12px;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    transition: border-color 0.15s, background 0.15s, transform 0.08s;
}
.provider-pill-card:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
}
.provider-pill-card.active {
    border-color: var(--ink-900);
    background: var(--ink-900);
    color: #fff;
}
.provider-pill-card.active .provider-pill-card-sub { color: rgba(255, 255, 255, 0.7); }
.provider-pill-card-name { font-weight: 600; font-size: 15px; }
.provider-pill-card-sub { font-size: 12px; color: var(--ink-500); }

/* Brand logo slot on each provider card. Fixed height so the grid
   rows line up even with different aspect ratios across the SVGs.
   White-out when the card is active (dark bg) — done via a filter
   because the SVGs have baked-in brand colors we can't theme. */
.provider-pill-logo {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    height: 22px;
    margin-bottom: 8px;
}
.provider-pill-logo svg { max-height: 100%; display: block; }
.provider-pill-card.active .provider-pill-logo svg {
    filter: brightness(0) invert(1);
}

/* Credentials form — was unstyled so labels rendered inline with
   inputs. Grid of two fields per row (single col on narrow widths),
   label stacked above each input. Matches Tito/Stripe's settings feel. */
.byo-creds-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 14px 18px;
    margin-bottom: 16px;
}
.byo-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.byo-field-label {
    font-size: 11.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-500);
}
.byo-field input,
.byo-field textarea {
    padding: 10px 12px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    font-size: 13px;
    color: var(--ink-900);
    background: var(--surface);
    width: 100%;
    box-sizing: border-box;
}
.byo-field input:focus,
.byo-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.12);
}
.byo-field textarea { font-family: inherit; resize: vertical; min-height: 72px; }

.byo-creds-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.byo-test-status {
    font-size: 12px;
    color: var(--ink-500);
}
.byo-test-status.ok { color: #16a34a; }
.byo-test-status.fail { color: #dc2626; }
.byo-test-status.testing { color: var(--ink-500); }

/* Standalone refund-policy row (no longer inside the payment card) */
.refund-policy-standalone {
    display: flex;
    align-items: center;
    gap: 16px;
}
.refund-policy-select-lg {
    flex: 1;
    max-width: 420px;
    padding: 12px 14px;
    border: 1.5px solid var(--ink-100);
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    background: var(--surface);
    cursor: pointer;
}
.refund-policy-select-lg:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.payments-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--ink-100);
}

/* ─── Custom domain card on /publish ─────────────────────────────────── */
#custom-domain-card details { display: block; }
#custom-domain-card summary {
    display: block;
    list-style: none;
    cursor: pointer;
}
#custom-domain-card summary::-webkit-details-marker,
#custom-domain-card summary::marker { display: none; }
.custom-domain-body {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--ink-100);
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.custom-domain-body label.field-full {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-900);
}
.custom-domain-body input {
    border: 1.5px solid var(--ink-100);
    border-radius: 8px;
    padding: 10px 14px;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 14px;
    background: var(--surface);
    color: var(--ink-900);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.custom-domain-body input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.custom-domain-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}
.cd-status {
    font-size: 12px;
    color: var(--ink-500);
    flex: 1;
}
.cd-status.saving { color: var(--ink-500); }
.cd-status.ok { color: #16a34a; font-weight: 600; }
.cd-status.fail { color: #dc2626; }

.custom-domain-instructions {
    background: #f9fafb;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    padding: 16px 18px;
    font-size: 13px;
    color: var(--ink-700);
    line-height: 1.55;
}
.custom-domain-instructions strong { color: var(--ink-900); }
.custom-domain-instructions p { margin: 8px 0; }
.dns-table {
    width: 100%;
    border-collapse: collapse;
    margin: 10px 0;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    overflow: hidden;
}
.dns-table th {
    text-align: left;
    padding: 8px 12px;
    background: #f3f4f6;
    color: var(--ink-500);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-bottom: 1px solid var(--ink-100);
}
.dns-table td {
    padding: 10px 12px;
    font-size: 13px;
    color: var(--ink-900);
}
.dns-table td.mono {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.cd-note {
    color: var(--ink-500);
    font-size: 12.5px;
    margin-top: 10px !important;
}

/* ─── Stripe Connect one-click panel ─────────────────────────────────── */
.stripe-connect-panel {
    background: linear-gradient(135deg, #f7fafc 0%, #eef2ff 100%);
    border: 1px solid #c7d2fe;
    border-radius: 12px;
    padding: 18px 20px;
    margin-bottom: 14px;
}
.stripe-connect-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    margin-bottom: 10px;
}
.stripe-connect-head strong {
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--ink-900);
    margin-bottom: 4px;
}
.stripe-connect-hint {
    display: block;
    font-size: 13px;
    color: var(--ink-500);
    line-height: 1.5;
    max-width: 420px;
}
.btn-stripe-connect {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 20px;
    background: #635BFF;  /* Stripe's brand purple */
    color: #fff;
    border: 0;
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 4px 14px -4px rgba(99, 91, 255, 0.5);
    transition: transform 0.08s, box-shadow 0.15s;
    white-space: nowrap;
    flex-shrink: 0;
}
.btn-stripe-connect:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 18px -4px rgba(99, 91, 255, 0.55);
    background: #554BEE;
}
.btn-stripe-connect:active { transform: translateY(0); }
.btn-stripe-connect:disabled { opacity: 0.6; cursor: wait; }
.stripe-connect-toggle {
    text-align: right;
    margin-top: 4px;
}

/* Post-OAuth success banner */
.stripe-success-banner {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 20px;
    background: linear-gradient(180deg, #ecfdf5, #f0fdf4);
    border: 1px solid #86efac;
    border-radius: 12px;
    margin-bottom: 20px;
    box-shadow: 0 4px 16px -8px rgba(22, 163, 74, 0.25);
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.25s ease-out, transform 0.25s ease-out;
}
/* display:flex above outranks the UA's [hidden] { display: none } because
   class beats attribute specificity. Without this rule the hidden banner
   still reserves its padding + margin + border, leaving a ~60px empty
   band between "Share & embed" and the embed card. */
.stripe-success-banner[hidden] { display: none !important; }
.stripe-success-banner.visible {
    opacity: 1;
    transform: translateY(0);
}
.stripe-success-check {
    width: 32px; height: 32px;
    border-radius: 999px;
    background: #16a34a;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 16px;
    flex-shrink: 0;
}
.stripe-success-banner strong {
    display: block;
    color: #065f46;
    font-size: 14px;
    font-weight: 700;
    margin-bottom: 2px;
}
.stripe-success-banner span:not(.stripe-success-check) {
    display: block;
    color: #065f46;
    font-size: 13px;
}
.stripe-success-banner > div { flex: 1; }
.stripe-success-banner .mini-btn {
    background: transparent;
    border: 0;
    color: #065f46;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    font-size: 14px;
}
.stripe-success-banner .mini-btn:hover { background: rgba(22, 163, 74, 0.1); }

/* ═══════════════════════════════════════════════════════════════════════
   Manage shell — post-create event workspace with left sidebar.
   Replaces the linear step-bar on /publish (and, in follow-ups,
   /payments + /registrations). Expandable: "Coming soon" group signals
   roadmap items (Check-in, Emails, Analytics, Team).
   ═══════════════════════════════════════════════════════════════════════ */

/* Header on manage pages: event name + status badge + primary Publish CTA.
   Reuses .studio-nav but re-slots the middle column for event meta. */
.manage-nav {
    grid-template-columns: auto 1fr auto;
}
.manage-event-meta {
    justify-self: start;
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}
.manage-event-name {
    font-size: 15px;
    font-weight: 600;
    color: var(--ink-900);
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 420px;
}
.manage-event-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    border: 1px solid var(--ink-100);
    background: var(--surface);
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
}
.manage-event-status .manage-status-dot {
    width: 7px;
    height: 7px;
    border-radius: 999px;
    background: var(--ink-300, #d4d4d8);
}
.manage-event-status.live {
    color: #065f46;
    background: #ecfdf5;
    border-color: #a7f3d0;
}
.manage-event-status.live .manage-status-dot {
    background: #16a34a;
    box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.2);
    animation: managePulse 1.8s infinite;
}
@keyframes managePulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.2); }
    50%      { box-shadow: 0 0 0 5px rgba(22, 163, 74, 0.05); }
}

/* ── Manage-header event switcher ─────────────────────────────────────
   The event-name span across every /registrations, /payments,
   /publish, /domain page is now a trigger button for the switcher
   dropdown. Collapsed state keeps the old visual weight (bold name,
   hover affordance) but adds a subtle chevron so the affordance is
   discoverable. Expanded state anchors a card below the button with
   a search input + the user's events. */
.manage-event-switcher { position: relative; display: inline-flex; align-items: center; }
.manage-event-switcher-trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: 1px solid transparent;
    padding: 4px 8px;
    border-radius: 8px;
    cursor: pointer;
    font: inherit;
    color: inherit;
    max-width: 100%;
}
.manage-event-switcher-trigger:hover,
.manage-event-switcher.open .manage-event-switcher-trigger {
    background: var(--ink-50, #f4f4f5);
    border-color: var(--ink-100);
}
.manage-event-switcher-trigger:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.manage-event-switcher-chev {
    color: var(--ink-500);
    font-size: 10px;
    line-height: 1;
    transition: transform 0.15s ease;
}
.manage-event-switcher.open .manage-event-switcher-chev { transform: rotate(180deg); }
.manage-event-switcher-menu[hidden] { display: none; }
.manage-event-switcher-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 80;
    min-width: 320px;
    max-width: 420px;
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    box-shadow: 0 20px 40px -18px rgba(0, 0, 0, 0.18), 0 4px 12px -6px rgba(0, 0, 0, 0.06);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.manage-event-switcher-search-wrap {
    padding: 10px 12px;
    border-bottom: 1px solid var(--ink-100);
    background: #fafafa;
}
.manage-event-switcher-search {
    width: 100%;
    padding: 7px 10px;
    font-size: 13px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    background: #fff;
    color: var(--ink-900);
}
.manage-event-switcher-search:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.manage-event-switcher-list {
    max-height: 360px;
    overflow-y: auto;
    padding: 6px;
}
.manage-event-switcher-state {
    padding: 14px 10px;
    font-size: 13px;
    color: var(--ink-500);
    text-align: center;
}
.manage-event-switcher-state.error { color: #b91c1c; }
.manage-event-switcher-row {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    background: transparent;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    text-align: left;
    font: inherit;
}
.manage-event-switcher-row:hover { background: var(--ink-50, #f4f4f5); }
.manage-event-switcher-row.is-current {
    background: #eef2ff;
    color: var(--ink-900);
}
.manage-event-switcher-row-name {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--ink-900);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.switcher-pill {
    font-size: 10px;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    flex-shrink: 0;
}
.switcher-pill.live  { background: #ecfdf5; color: #065f46; }
.switcher-pill.draft { background: #f3f4f6; color: #52525b; }
.switcher-current-mark {
    color: var(--accent);
    font-weight: 700;
    flex-shrink: 0;
}
.manage-event-switcher-all {
    padding: 10px 14px;
    border-top: 1px solid var(--ink-100);
    background: #fafafa;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-700);
    text-decoration: none;
    text-align: center;
}
.manage-event-switcher-all:hover { background: #f3f4f6; color: var(--ink-900); }

/* Inside the trigger the event name reuses its old look — max-width
   shrinks to leave room for the chevron. */
.manage-event-switcher-trigger .manage-event-name { max-width: 360px; }
.manage-nav-right {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 14px;
}

/* Two-column layout: sidebar + main content. Sidebar sticks.
   `minmax(0, 1fr)` instead of bare `1fr` so a wide grandchild (a long
   <table>, the .plans-grid 240px-min cards, an unbroken text run) can
   never push the main column past its share — that was making the
   anonymous /v3/plans view balloon to ~624px on a 398px viewport,
   which let auto-fit place 2 plan cards per row and chopped the right
   card off the screen. With `minmax(0, …)` the column shrinks to
   viewport and overflowing children stay inside their own scroll
   wrapper instead of stretching the page. */
.manage-layout {
    display: grid;
    grid-template-columns: 240px minmax(0, 1fr);
    gap: 0;
    min-height: calc(100vh - 64px);
    align-items: start;
}
/* Anonymous-visitor variant — public /v3/plans renders the account
   shell without a sidebar (since the account nav is meaningless until
   sign-up). Make main span the full grid so there's no 240px void on
   the left. min-width: 0 belt-and-braces against the same overflow
   path on viewports where the @media below has already collapsed the
   layout to a single column. */
.manage-main-full {
    grid-column: 1 / -1;
    max-width: 1280px;
    margin: 0 auto;
    width: 100%;
    min-width: 0;
}
.manage-sidebar {
    position: sticky;
    top: 64px;
    align-self: start;
    height: calc(100vh - 64px);
    overflow-y: auto;
    border-right: 1px solid var(--ink-100);
    padding: 22px 14px 40px;
    background: var(--surface);
}
.manage-nav-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.manage-nav-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 10px 12px 6px;
}
.manage-nav-label-sub { margin-top: 18px; }

.manage-nav-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 12px;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--ink-700);
    border-radius: 8px;
    text-decoration: none;
    transition: background 0.12s, color 0.12s;
    cursor: pointer;
    line-height: 1.3;
}
.manage-nav-item:hover {
    background: #f5f5f7;
    color: var(--ink-900);
}
.manage-nav-item.active {
    background: var(--ink-900);
    color: #fff;
}
.manage-nav-item.active:hover { background: var(--ink-900); }

.manage-nav-item.locked {
    color: var(--ink-300, #b8b8bf);
    cursor: default;
    font-weight: 500;
}

/* ── /v3/studio/{id}/publish — Share & embed (new layout) ───────────
   Preview-first hierarchy: the hosted landing iframe is the hero at
   the top of the page, a mode switcher (Popup / Inline / Hosted URL)
   sits beneath, and only the snippet/URL row for the active mode is
   shown. Scoped under .share-preview-stage / .share-mode-* so the
   legacy .embed-mode-* classes (still used elsewhere) stay untouched. */
.share-preview-stage {
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 18px 42px -28px rgba(11, 15, 25, 0.25);
    margin-bottom: 18px;
}
.share-preview-chrome {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    background: #f6f6f8;
    border-bottom: 1px solid var(--ink-100);
    font-size: 12px;
    color: var(--ink-500);
}
.spc-dots { display: inline-flex; gap: 6px; flex-shrink: 0; }
.spc-dot { width: 11px; height: 11px; border-radius: 50%; background: #d1d5db; }
.spc-dot-r { background: #ff5f57; }
.spc-dot-y { background: #ffbd2e; }
.spc-dot-g { background: #28c840; }
.spc-url {
    flex: 1; min-width: 0;
    padding: 6px 12px; background: #fff; border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px; color: var(--ink-700);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.spc-open {
    font-size: 12px; font-weight: 500; color: var(--ink-500);
    text-decoration: none; padding: 4px 8px; border-radius: 6px;
    flex-shrink: 0;
}
.spc-open:hover { background: #eceef2; color: var(--ink-900); }
.share-preview-frame {
    position: relative;
    /* Aspect-ratio box sized so the scaled 1440×900 desktop iframe below
       fits the container width exactly. Height = containerWidth * 900/1440. */
    aspect-ratio: 1440 / 900;
    max-height: 560px;
    background: #fff;
    overflow: hidden;
}
.share-preview-frame iframe {
    /* Render the landing page at a real desktop viewport so the hero
       renders in its intended split layout, then scale the whole thing
       down to fit the preview box. JS sets --share-preview-scale based
       on container width; CSS fallback uses 0.62 which matches the
       ~896px content column at desktop. */
    width: 1440px;
    height: 900px;
    border: 0;
    display: block;
    transform-origin: 0 0;
    transform: scale(var(--share-preview-scale, 0.62));
}
/* Floating Register-popup button — overlays the preview iframe at
   bottom-right. Demonstrates what the popup embed feels like on a
   third-party site. data-visible="false" hides in inline / URL mode. */
.share-preview-pop {
    position: absolute;
    right: 22px; bottom: 22px;
    display: flex; align-items: center; gap: 10px;
    transition: opacity 0.2s, transform 0.2s;
}
.share-preview-pop[data-visible="false"] {
    opacity: 0; transform: translateY(8px); pointer-events: none;
}
.spp-hint {
    background: var(--ink-900); color: #fff;
    font-size: 11px; font-weight: 600; letter-spacing: 0.3px;
    padding: 5px 9px; border-radius: 6px;
    position: relative;
    box-shadow: 0 8px 20px -10px rgba(0,0,0,0.35);
}
.spp-hint::after {
    content: ''; position: absolute; right: -4px; top: 50%;
    transform: translateY(-50%) rotate(45deg);
    width: 8px; height: 8px; background: var(--ink-900);
}
.spp-btn {
    /* Uses the same widget.js .e2m-btn styles as the real embed, so if
       the organiser restyles .e2m-btn later this demo updates too. */
    box-shadow: 0 18px 36px -12px rgba(11, 15, 25, 0.45);
    animation: spp-nudge 2.8s ease-in-out infinite;
}
@keyframes spp-nudge {
    0%, 70%, 100% { transform: translateY(0); }
    80%           { transform: translateY(-4px); }
    90%           { transform: translateY(-1px); }
}

/* Mode switcher — compact segmented pills. The default pill gets a
   tiny "Default" badge so "popup is what attendees see out of the
   box" reads without a tooltip. */
.share-modes {
    display: inline-flex;
    gap: 6px;
    padding: 5px;
    background: #f3f0ea;
    border-radius: 12px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}
.share-mode-pill {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 14px;
    font: inherit; font-size: 13px; font-weight: 500;
    color: var(--ink-700);
    background: transparent;
    border: 0;
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, box-shadow 0.12s;
}
.share-mode-pill:hover { color: var(--ink-900); }
.share-mode-pill.active {
    background: #fff;
    color: var(--ink-900);
    font-weight: 600;
    box-shadow: 0 2px 6px rgba(11, 15, 25, 0.08);
}
.share-mode-pill svg { opacity: 0.8; }
.share-mode-default {
    font-size: 10px; font-weight: 700; letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 2px 6px; border-radius: 999px;
    background: #e0e7ff; color: #3730a3;
    margin-left: 2px;
}
.share-mode-pill.active .share-mode-default { background: #eef2ff; }

.share-mode-panel {
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    padding: 16px 18px;
}
.share-mode-panel-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; margin-bottom: 12px;
}
.share-mode-panel-head strong {
    display: block; font-size: 14px; font-weight: 600; color: var(--ink-900);
}
.share-mode-panel-head span {
    display: block; font-size: 12.5px; color: var(--ink-500); margin-top: 2px;
}
.share-mode-panel-head code {
    background: #f3f4f6; border: 1px solid var(--ink-100);
    border-radius: 4px; padding: 0 5px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px; color: var(--ink-900);
}

.share-snippet {
    /* Light code block — previously dark (var(--ink-900)), which made
       it visually merge with the adjacent dark "Copy snippet" and
       "Try the popup" CTA buttons. Light-grey surface + indigo
       syntax-ish text reads as "code to copy" without competing with
       the button row. Monospace + subtle border keeps it recognisable
       as a code affordance. */
    background: #f8fafc;
    color: #1e293b;
    border: 1px solid var(--ink-100);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px; line-height: 1.55;
    padding: 14px 16px;
    border-radius: 10px;
    white-space: pre-wrap; word-break: break-word;
    margin: 0 0 14px;
    overflow: auto;
}

.share-mode-foot {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    font-size: 12.5px; color: var(--ink-500);
}
.share-mode-demo { flex-shrink: 0; }
.share-mode-foot-chips { gap: 8px; }
.share-mode-foot-label {
    font-size: 11.5px; font-weight: 600; color: var(--ink-500);
    text-transform: uppercase; letter-spacing: 0.4px;
    margin-right: 2px;
}

.share-url-row {
    display: flex; align-items: stretch; gap: 8px;
    margin-bottom: 12px;
}
.share-url-row input {
    flex: 1; min-width: 0;
    padding: 9px 12px; border: 1.5px solid var(--ink-100);
    border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px; color: var(--ink-900);
    background: #fafafa;
}
.share-url-row input:focus { outline: none; border-color: var(--accent); background: #fff; }
.share-url-row .share-preview-link { align-self: center; flex-shrink: 0; }

/* Off-screen live signal — only exists so legacy post-publish JS can
   flip class names + text without touching the new preview/snippet
   layout. Hidden from layout entirely. */
.share-live-signal {
    position: absolute; left: -9999px; width: 1px; height: 1px;
    overflow: hidden;
}

@media (max-width: 720px) {
    .share-preview-frame { max-height: 420px; }
    .spc-url { font-size: 11px; }
    .share-preview-pop { right: 14px; bottom: 14px; }
    .spp-hint { display: none; }
    .share-mode-panel-head { flex-direction: column; }
    .share-mode-panel-head .btn-primary { align-self: flex-start; }
}

/* "← Back" entry pinned above the nav groups. Lighter weight + a
   hairline under it so it reads as a navigational escape hatch, not
   a same-level menu item. */
.manage-nav-item.manage-nav-back {
    color: var(--ink-500);
    font-weight: 500;
    margin-bottom: 12px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--ink-100);
    border-radius: 8px 8px 0 0;
}
.manage-nav-item.manage-nav-back:hover { color: var(--ink-900); background: transparent; }
.manage-nav-item.locked::after {
    content: 'soon';
    font-size: 9.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    background: var(--ink-100);
    color: var(--ink-500);
    padding: 2px 6px;
    border-radius: 4px;
}
.manage-nav-item.locked:hover { background: transparent; color: var(--ink-300, #b8b8bf); }

/* Warning dot for the Payments item when a paid event lacks a verified
   payment config — same signal the pay-required banner carries. */
.manage-nav-warn {
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: #f59e0b;
    box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18);
    flex-shrink: 0;
}
.manage-nav-item.needs-attention { color: var(--ink-900); font-weight: 600; }
/* When the current-page ink-900 background coincides with needs-attention
   (you're on the Payments screen AND payments still need wiring), the two
   rules stacked before made the label the same colour as the background —
   a dark bar with an invisible "Payments" word, per the BIT Mesra screenshot.
   This combined selector wins over both and restores the white label. */
.manage-nav-item.active.needs-attention { color: #fff; }

/* Main content area — same max-width feel as old .publish-main, but sits
   inside the layout grid so it breathes with the sidebar. */
.manage-main {
    max-width: 960px;
    width: 100%;
    margin: 0 auto;
    padding: 40px 32px 80px;
    box-sizing: border-box;
}
.manage-section-head { margin-bottom: 24px; }
.manage-section-head h1 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 36px;
    letter-spacing: -0.01em;
    margin: 0 0 6px;
    color: var(--ink-900);
}
.manage-section-head p {
    color: var(--ink-500);
    font-size: 14.5px;
    margin: 0;
}

/* /publish: tighten top rhythm so "Share & embed" lands closer to
   actionable content and avoids a large dead band above the first card.
   Numbers halved vs the initial pass — user shot showed >200px of empty
   space between the page nav and the first actionable element. */
.publish-manage-main { padding-top: 16px; padding-bottom: 48px; }
.publish-manage-main .manage-section-head { margin-bottom: 10px; }
.publish-manage-main .manage-section-head h1 { font-size: 32px; }
.manage-main .pay-required-banner {
    margin: 0 0 12px;
    position: sticky;
    top: 8px;
    z-index: 20;
}
.publish-manage-main .stripe-success-banner { margin-bottom: 12px; }

/* Publish disclosure — modal shown pre-publish on paid + e2m_managed
   events. Backdrop + centered card, tight on numbers. Esc / backdrop
   click / Cancel all resolve as "no, don't publish" in the JS wiring.

   z-index sits at 9999 to match the convention documented on
   .studio-nav above — the sticky nav (z=50) creates its own stacking
   context, and at z=200 the overlay was being out-ranked, letting the
   Back + Publish buttons in the nav poke through the scrim and read
   as clickable while a blocking modal was open. 9999 puts the overlay
   above every in-page floater (TOC z=40, regen overlay z=30, refund
   drawer z=100) AND clears the nav's stacking trap. */
.publish-disclosure-overlay {
    /* Defensive !important on the props that govern "is this floating
       above the page". Two prior bugs traced back to this: the sticky
       nav's stacking context out-ranking us, and other stylesheets
       redefining .publish-disclosure-overlay with position: relative.
       The !important here can't be over-ridden by another stylesheet
       loading later in the cascade. Other props (padding, transition,
       backdrop blur) stay overridable for theming. */
    position: fixed !important;
    top: 0 !important; right: 0 !important;
    bottom: 0 !important; left: 0 !important;
    inset: 0 !important;
    z-index: 9999 !important;
    display: flex !important;
    align-items: center !important; justify-content: center !important;
    background: rgba(15, 23, 42, 0.55);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    padding: 20px;
    margin: 0;
    width: auto; height: auto;
    transform: none;
    opacity: 0;
    transition: opacity 0.18s ease;
}
.publish-disclosure-overlay.open { opacity: 1; }
.publish-disclosure-overlay[hidden] { display: none !important; }
.publish-disclosure-modal {
    background: #fff;
    border-radius: 16px;
    padding: 28px 28px 22px;
    max-width: 460px;
    width: 100%;
    box-shadow: 0 28px 80px -20px rgba(15, 23, 42, 0.5);
    transform: translateY(12px);
    transition: transform 0.2s ease;
}
.publish-disclosure-overlay.open .publish-disclosure-modal { transform: translateY(0); }
.publish-disclosure-modal h2 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 26px;
    letter-spacing: -0.01em;
    color: var(--ink-900);
    margin: 0 0 10px;
}
.publish-disclosure-modal > p {
    font-size: 14px;
    color: var(--ink-700);
    line-height: 1.55;
    margin: 0 0 14px;
}
.publish-disclosure-list {
    list-style: none;
    padding: 0;
    margin: 0 0 14px;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    overflow: hidden;
}
.publish-disclosure-list li {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 10px 14px;
    font-size: 13px;
    color: var(--ink-700);
    border-bottom: 1px solid #f3f4f6;
}
.publish-disclosure-list li:last-child { border-bottom: none; }
.publish-disclosure-list li strong { color: var(--ink-500); font-weight: 500; font-size: 12px; }
.publish-disclosure-list li span { color: var(--ink-900); font-weight: 600; text-align: right; }
.publish-disclosure-note {
    font-size: 12.5px;
    color: var(--ink-500);
    line-height: 1.55;
    margin: 0 0 16px;
}
.publish-disclosure-note a { color: var(--accent); }
.publish-disclosure-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    flex-wrap: wrap;
}
.publish-disclosure-actions .btn-primary { padding: 9px 18px; font-weight: 600; }
.publish-disclosure-actions .btn-ghost { padding: 9px 14px; font-size: 13px; }
@media (max-width: 520px) {
    .publish-disclosure-modal { padding: 22px 20px 18px; }
    .publish-disclosure-actions { flex-direction: column-reverse; }
    .publish-disclosure-actions > * { width: 100%; text-align: center; }
}

/* Header CTA badge — sits to the LEFT of the publish button to give
   organisers a one-glance read of state (Edits pending / Hidden / Ended).
   Colour-coded by severity; "Edits pending" gets the loudest treatment
   because it's the actionable signal. */
.publish-cta-badge {
    display: inline-flex; align-items: center;
    padding: 4px 10px; margin-right: 4px;
    font-size: 11.5px; font-weight: 600;
    letter-spacing: 0.01em;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}
.publish-cta-badge--draft         { background: #f3f4f6; color: #4b5563; border-color: #e5e7eb; }
.publish-cta-badge--live_in_sync  { background: #ecfdf5; color: #047857; border-color: #a7f3d0; }
.publish-cta-badge--live_dirty    { background: #fff7ed; color: #c2410c; border-color: #fed7aa; }
.publish-cta-badge--unlisted      { background: #fef2f2; color: #b91c1c; border-color: #fecaca; }
.publish-cta-badge--past          { background: #f5f5f4; color: #57534e; border-color: #e7e5e4; }
.publish-cta-badge--viewer        { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }

/* Disabled-link variant — anchors can't use :disabled, so we mirror it. */
.btn-primary.is-disabled,
.btn-primary[aria-disabled="true"] {
    opacity: 0.55;
    pointer-events: none;
    cursor: not-allowed;
}

/* Each logical block (share/receipts/domain) separated by a subtle rule.
   Use sibling-aware rules instead of :first-of-type because headings use
   <section> too; :first-of-type caused accidental top gaps. */
.manage-main > .manage-block { margin-top: 36px; scroll-margin-top: 72px; }
.manage-main > .manage-section-head + .manage-block { margin-top: 0; }
.manage-main > .pay-required-banner + .manage-block { margin-top: 0; }
.manage-block-head { margin: 0 0 14px; }
.manage-block-head h2 {
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.005em;
    margin: 0 0 4px;
    color: var(--ink-900);
}
.manage-block-head p {
    color: var(--ink-500);
    font-size: 13.5px;
    margin: 0;
}

.manage-details-chevron {
    margin-left: auto;
    color: var(--ink-500);
    transition: transform 0.15s;
}
details[open] > summary .manage-details-chevron { transform: rotate(180deg); }

/* Slim embed-card footer — replaces the old big .embed-try box. One
   row: contextual hint · demo button · open-in-new-tab link. */
.embed-foot {
    margin-top: 12px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.embed-foot-hint {
    color: var(--ink-500);
    font-size: 13px;
    line-height: 1.45;
    flex: 1 1 auto;
    min-width: 260px;
}
.embed-foot-hint code {
    font-family: 'SF Mono', Menlo, Consolas, monospace;
    font-size: 12px;
    padding: 1px 6px;
    background: #f3f4f6;
    border-radius: 4px;
    color: var(--ink-700);
}
.embed-foot-demo {
    flex-shrink: 0;
    padding: 6px 14px !important;
    font-size: 12px !important;
}

/* Slim share strip — replaces old .live-banner hero + hosted-preview card.
   Two rows on wide, stacks on narrow. URL input grows, chips are square
   icons (40×40). The pulsing green dot signals live state. */
.share-strip {
    margin-top: 18px;
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.share-strip.is-live { background: #f0fdf4; border-color: #bbf7d0; }
.share-strip-lead {
    display: flex;
    align-items: center;
    gap: 10px;
}
.share-strip-lead .live-dot {
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: var(--ink-300, #9ca3af);
    flex-shrink: 0;
}
.share-strip.is-live .live-dot {
    background: #16a34a;
    box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.2);
    animation: managePulse 1.8s infinite;
}
.share-strip-copy { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.share-strip .live-title { font-size: 13.5px; font-weight: 600; color: var(--ink-900); }
.share-strip .live-sub   { font-size: 12.5px; color: var(--ink-500); }
.share-strip-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.share-strip-row input {
    flex: 1 1 280px;
    min-width: 0;
    border: 1px solid var(--ink-100);
    background: var(--surface);
    border-radius: 8px;
    padding: 8px 12px;
    font-size: 13px;
    color: var(--ink-700);
    font-family: inherit;
}
.share-strip-row > .btn-primary {
    padding: 8px 14px;
    font-size: 13px;
    flex-shrink: 0;
}
.share-preview-link { flex-shrink: 0; font-size: 12.5px; }
.share-strip-sep {
    width: 1px;
    height: 22px;
    background: var(--ink-100);
    margin: 0 2px;
    flex-shrink: 0;
}
.share-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--ink-100);
    background: var(--surface);
    color: var(--ink-700);
    flex-shrink: 0;
    transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.share-chip:hover { border-color: var(--ink-300, #9ca3af); color: var(--ink-900); }
.share-chip.share-whatsapp:hover { color: #25d366; border-color: #25d366; background: #f0fdf4; }
.share-chip.share-linkedin:hover { color: #0a66c2; border-color: #0a66c2; background: #eff6ff; }

/* Landing-page context preview — a small iframe of the hosted landing
   so the organizer can see what their share link actually looks like.
   Height is clipped so only the top fold is visible (hero + reg form). */
.landing-context-preview {
    margin-top: 18px;
    border: 1px solid var(--ink-100);
    border-radius: var(--radius-lg);
    background: #f3f4f6;
    overflow: hidden;
}
.landing-context-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--ink-100);
}
.landing-context-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.landing-context-preview iframe {
    width: 100%;
    height: 520px;
    border: 0;
    background: var(--surface);
    display: block;
}

/* Responsive — collapse sidebar below 900px. Users on phones shouldn't
   see the full IA; a horizontal row of pills would be the follow-up. */
@media (max-width: 900px) {
    .manage-layout { grid-template-columns: minmax(0, 1fr); }
    .manage-sidebar {
        position: static;
        height: auto;
        border-right: 0;
        border-bottom: 1px solid var(--ink-100);
        padding: 12px 14px;
    }
    .manage-nav-list { flex-direction: row; flex-wrap: wrap; gap: 4px; }
    .manage-nav-label { display: none; }
    .manage-nav-item.locked { display: none; }
    .manage-main { padding: 28px 20px 60px; }
    .manage-event-name { max-width: 180px; }
}

/* ─── Platform admin (/admin/platform/*) ───────────────────────────────
   Reuses .manage-sidebar / .manage-main / .publish-card shells so the
   shape matches the per-event manage screens the organizer already
   knows. Only the platform-specific bits (stat cards, dense table
   rows, env-var display, foot pill) need net-new styles. */
.platform-sidebar { display: flex; flex-direction: column; }
.platform-sidebar-foot {
    margin-top: auto;
    padding: 14px 12px 4px;
    font-size: 11.5px;
    color: var(--ink-500);
    display: flex; flex-direction: column; gap: 4px;
    border-top: 1px dashed var(--ink-100);
}
.platform-access-note {
    display: inline-flex; align-items: center; gap: 6px;
    color: #92400e;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 10.5px;
}
.platform-access-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: #f59e0b;
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.18);
}
.platform-user { font-size: 11px; color: var(--ink-500); word-break: break-all; }

.platform-stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    margin-bottom: 6px;
}
.platform-stat-card {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    padding: 16px 18px;
    display: flex; flex-direction: column; gap: 4px;
    box-shadow: var(--shadow-sm);
}
.platform-stat-label {
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.platform-stat-value {
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 32px;
    font-weight: 400;
    color: var(--ink-900);
    line-height: 1.05;
    letter-spacing: -0.01em;
}
.platform-stat-sub { font-size: 12px; color: var(--ink-500); }

.platform-quick-links {
    list-style: none;
    padding: 0; margin: 0;
    display: flex; flex-direction: column;
}
.platform-quick-links li {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 14px;
    padding: 10px 0;
    border-bottom: 1px solid #f3f4f6;
}
.platform-quick-links li:last-child { border-bottom: none; }
.platform-quick-links a {
    font-weight: 600;
    color: var(--ink-900);
    text-decoration: none;
}
.platform-quick-links a:hover { color: var(--accent); text-decoration: underline; }
.platform-quick-links li span { font-size: 12.5px; color: var(--ink-500); text-align: right; }

/* Filter bar above platform tables — free-text search + status/pay
   dropdowns + live result counter. Client-side only; hides rows via
   .row-hidden. Matches the look of .platform-table for a tight feel. */
.platform-filter-bar {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.platform-filter-bar input[type="search"] {
    flex: 1 1 320px;
    min-width: 220px;
    padding: 8px 12px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-size: 13px;
    font-family: inherit;
    background: var(--surface);
    color: var(--ink-900);
}
.platform-filter-bar input[type="search"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.12);
}
.platform-filter-bar select {
    padding: 8px 12px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-size: 13px;
    font-family: inherit;
    background: var(--surface);
    color: var(--ink-700);
    cursor: pointer;
}
.platform-filter-count {
    font-size: 12px;
    color: var(--ink-500);
    margin-left: auto;
    white-space: nowrap;
}
.platform-row-link {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
}
.platform-row-link:hover { text-decoration: underline; }

/* Filtered-out rows — hidden via display:none so the table reflows
   and the count is honest. */
.platform-table tbody tr.row-hidden { display: none; }

/* Fee-form inputs — inline number fields on /admin/platform/fees.
   Compact enough to fit inside the table cell without breaking the
   row height. Override-flag dot signals that the current value is
   a DB override of the code default. */
.fee-input {
    width: 110px;
    padding: 6px 10px;
    border: 1px solid var(--ink-100);
    border-radius: 6px;
    font-size: 13px;
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    background: var(--surface);
    color: var(--ink-900);
}
.fee-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.fee-override-flag {
    display: inline-block;
    margin-left: 8px;
    color: #f59e0b;
    font-size: 14px;
    vertical-align: middle;
}

/* Provider edit form — label/notes inputs + enable toggle. Sits inline
   inside the platform-table so the admin can scan all four providers
   at once and edit in place. */
.provider-key {
    display: inline-block;
    font-size: 12px;
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    font-weight: 600;
    color: var(--ink-900);
    background: #f3f4f6;
    padding: 2px 8px;
    border-radius: 6px;
    border: 1px solid var(--ink-100);
}
.provider-input {
    display: block;
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--ink-100);
    border-radius: 6px;
    font-size: 13px;
    font-family: inherit;
    background: var(--surface);
    color: var(--ink-900);
    margin-bottom: 6px;
}
.provider-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.provider-input.provider-label { font-weight: 600; }
.provider-input.provider-notes { font-size: 12.5px; color: var(--ink-500); }
.provider-row.provider-disabled .provider-key,
.provider-row.provider-disabled .provider-input { opacity: 0.55; }

/* Tiny on/off toggle — plain checkbox styled as a pill. */
.provider-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-700);
    cursor: pointer;
    user-select: none;
}
.provider-toggle input[type="checkbox"] {
    appearance: none;
    width: 32px;
    height: 18px;
    border-radius: 999px;
    background: #d1d5db;
    position: relative;
    cursor: pointer;
    transition: background 0.15s;
    border: 0;
    margin: 0;
}
.provider-toggle input[type="checkbox"]::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    border-radius: 999px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    transition: transform 0.15s;
}
.provider-toggle input[type="checkbox"]:checked {
    background: #16a34a;
}
.provider-toggle input[type="checkbox"]:checked::after {
    transform: translateX(14px);
}

.platform-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    color: var(--ink-700);
}
.platform-table thead th {
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 12px 16px;
    background: #fafafa;
    border-bottom: 1px solid var(--ink-100);
}
.platform-table tbody td {
    padding: 12px 16px;
    border-bottom: 1px solid #f3f4f6;
    vertical-align: top;
}
.platform-table tbody tr:last-child td { border-bottom: none; }
.platform-row-sub {
    font-size: 11.5px;
    color: var(--ink-500);
    margin-top: 2px;
}
.platform-envline {
    display: flex; align-items: center; gap: 10px;
    margin-bottom: 3px;
    font-size: 12px;
}
.platform-envline code {
    background: #f3f4f6;
    border: 1px solid var(--ink-100);
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 11px;
    color: var(--ink-900);
}
.platform-envvalue {
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    color: var(--ink-700);
    font-size: 12px;
}
.platform-envvalue.unset { color: #b45309; font-style: italic; }
.platform-mono {
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
    font-size: 12px;
    color: var(--ink-700);
}
.platform-muted { color: var(--ink-500); font-size: 12px; }
.platform-country-pill {
    display: inline-block;
    padding: 2px 8px;
    background: var(--accent-soft);
    color: var(--accent);
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    margin-right: 4px;
    margin-bottom: 2px;
}
.platform-badge {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: #f3f4f6;
    color: var(--ink-700);
}
.platform-badge.ok { background: #dcfce7; color: #166534; }
.platform-badge.warn { background: #fef3c7; color: #92400e; }

/* Provider-status pills on /admin/platform/integrations/mail. Green
   when the provider is configured, neutral grey when it isn't. The
   send order strip uses these to make the active/inactive rails
   visible at a glance. */
.platform-pill {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    border: 1px solid transparent;
}
.platform-pill-on {
    background: #dcfce7;
    color: #166534;
    border-color: #a7f3d0;
}
.platform-pill-off {
    background: #f3f4f6;
    color: #6b7280;
    border-color: #e5e7eb;
}

/* ─── Plans editor + pricing matrix ───────────────────────────────────── */
/* Country switcher on the Plans page. Horizontal scroll strip of flag +
   name pills. Renders the currently-selected locale summary in bold so
   the page doesn't need two spots to show "what am I looking at". */
.country-switcher {
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 12px;
    padding: 16px 18px 14px;
    margin-bottom: 20px;
    box-shadow: var(--shadow-sm);
}
.country-switcher-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}
.country-switcher-label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.country-switcher-current {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-900);
}
.country-switcher-pills {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.country-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 999px;
    font-size: 12.5px;
    color: var(--ink-700);
    text-decoration: none;
    transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.country-pill:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
}
.country-pill.active {
    border-color: var(--ink-900);
    background: var(--ink-900);
    color: #fff;
    font-weight: 600;
}
.country-pill .country-flag { font-size: 14px; line-height: 1; }

/* Local-price annotation under a plan card's USD headline. Lives in the
   same column as .plan-price and shares the bottom border; no extra
   margin so cards don't lengthen when the switcher is off. */
.plan-price-local {
    display: flex;
    align-items: baseline;
    gap: 6px;
    font-size: 13px;
    color: var(--ink-500);
    margin: -14px 0 0;
    padding: 0 0 14px;
    border-bottom: 1px solid var(--ink-100);
    flex-wrap: wrap;
}
.plan-price-local-tax {
    font-size: 11.5px;
    color: var(--ink-500);
    font-weight: 500;
    background: #f3f4f6;
    border-radius: 4px;
    padding: 1px 6px;
}

.plan-matrix {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 14px;
    margin-bottom: 8px;
}
.plan-card {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--ink-100);
    border-radius: 14px;
    padding: 24px 22px 20px;
    box-shadow: var(--shadow-sm);
    display: flex; flex-direction: column;
    min-height: 100%;
}
.plan-card-featured {
    border-color: var(--accent);
    box-shadow: 0 12px 32px -16px rgba(79, 70, 229, 0.35), 0 0 0 3px rgba(79, 70, 229, 0.08);
    transform: translateY(-4px);
}
.plan-badge {
    position: absolute;
    top: -12px; left: 22px;
    padding: 4px 10px;
    background: var(--accent);
    color: #fff;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    box-shadow: 0 4px 12px -4px rgba(79, 70, 229, 0.5);
}
.plan-card-head h3 {
    font-family: 'Instrument Serif', Georgia, serif;
    font-weight: 400;
    font-size: 28px;
    color: var(--ink-900);
    margin: 0 0 6px;
    letter-spacing: -0.01em;
}
.plan-tagline {
    font-size: 13px;
    color: var(--ink-500);
    line-height: 1.5;
    margin: 0 0 18px;
    min-height: 40px;
}
.plan-price {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--ink-100);
}
.plan-price-amount {
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 48px;
    font-weight: 400;
    color: var(--ink-900);
    line-height: 1;
    letter-spacing: -0.02em;
}
.plan-price-contact {
    font-family: 'Instrument Serif', Georgia, serif;
    font-size: 32px;
    font-weight: 400;
    color: var(--ink-900);
    line-height: 1;
    letter-spacing: -0.01em;
}
.plan-price-cadence {
    font-size: 13px;
    color: var(--ink-500);
}
.plan-cta-placeholder {
    margin: 16px 0 10px;
    padding: 11px 18px;
    background: var(--ink-900);
    color: #fff;
    border-radius: 10px;
    text-align: center;
    font-size: 14px;
    font-weight: 600;
    cursor: default;
    letter-spacing: -0.005em;
}
.plan-card-featured .plan-cta-placeholder { background: var(--accent); }
.plan-feature-list {
    list-style: none;
    padding: 0;
    margin: 10px 0 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.plan-feature-list li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 13px;
    color: var(--ink-700);
    line-height: 1.5;
}
.plan-feature-tick {
    display: inline-flex;
    width: 16px; height: 16px; flex-shrink: 0;
    align-items: center; justify-content: center;
    background: #dcfce7;
    color: #166534;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 700;
    margin-top: 2px;
}
.plan-feature-label { flex: 1; min-width: 0; }
.plan-feature-detail { color: var(--ink-500); }

.plan-edit-card { margin-bottom: 18px; }
.plan-edit-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 16px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--ink-100);
    flex-wrap: wrap;
}
.plan-edit-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--ink-900);
    margin: 0 0 2px;
    letter-spacing: -0.005em;
}
.plan-edit-key {
    display: inline-block;
    background: #f3f4f6;
    border: 1px solid var(--ink-100);
    border-radius: 4px;
    padding: 1px 6px;
    font-size: 11px;
    color: var(--ink-500);
    font-family: ui-monospace, SFMono-Regular, Consolas, Menlo, monospace;
}
.plan-edit-toggles { display: flex; gap: 16px; flex-wrap: wrap; }
.platform-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--ink-700);
    cursor: pointer;
}
.platform-toggle input { accent-color: var(--accent); }
.plan-edit-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px 14px;
}
.plan-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ink-500);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.plan-field-wide { grid-column: span 2; }
.plan-field small {
    font-weight: 400;
    text-transform: none;
    letter-spacing: normal;
    color: var(--ink-500);
    margin-left: 4px;
}
.plan-field input {
    padding: 8px 10px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 400;
    color: var(--ink-900);
    text-transform: none;
    letter-spacing: normal;
    background: var(--surface);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.plan-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.plan-edit-actions { margin-top: 16px; display: flex; justify-content: flex-end; }
@media (max-width: 720px) {
    .plan-matrix { grid-template-columns: 1fr; }
    .plan-card-featured { transform: none; }
    .plan-field-wide { grid-column: auto; }
}

/* ── /v3/account/showcase ─────────────────────────────────────────────
   Event showcase / multi-event hub control panel. Styles are scoped to
   .showcase-* classes so they don't leak into the legacy per-event
   domain page that still uses the .cd-* / .dns-table vocabulary. */
.showcase-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}
.showcase-summary-stats {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
}
.showcase-stat { display: flex; flex-direction: column; gap: 2px; }
.showcase-stat strong { font-size: 22px; font-weight: 700; color: var(--ink-900); line-height: 1.1; text-transform: capitalize; }
.showcase-stat span { font-size: 12px; color: var(--ink-500); }

/* ── Accordion (global-standard <details> pattern) ─────────────
   White card, subtle 1px border, chevron on the right, opens
   smoothly. Identical affordance across all showcase sections so
   the page reads as one scan-able list rather than a pile of
   different card styles. No coloured left borders anywhere — flat
   neutrals only. Mirrors the pattern used in Notion / Stripe
   dashboard / Apple System Settings. */
.showcase-acc {
    background: #fff;
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    margin-top: 14px;
    overflow: hidden;
    transition: box-shadow 0.12s;
}
.showcase-acc + .showcase-acc { margin-top: 10px; }
.showcase-acc:hover { box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); }
.showcase-acc[open] { box-shadow: 0 2px 10px -4px rgba(15, 23, 42, 0.06); }

.showcase-acc-summary {
    list-style: none;
    cursor: pointer;
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px;
    padding: 14px 18px;
    user-select: none;
}
.showcase-acc-summary::-webkit-details-marker { display: none; }
.showcase-acc-summary:hover { background: #fafafa; }
.showcase-acc[open] > .showcase-acc-summary { border-bottom: 1px solid var(--ink-100); }

.showcase-acc-title-group {
    display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.showcase-acc-title {
    font-size: 14px; font-weight: 600;
    color: var(--ink-900);
    letter-spacing: -0.005em;
}
.showcase-acc-sub {
    font-size: 12.5px;
    color: var(--ink-500);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.showcase-acc-sub code {
    background: var(--ink-100); color: var(--ink-700);
    padding: 0 5px; border-radius: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
}
.showcase-acc-meta {
    display: inline-flex; align-items: center; gap: 14px; flex-shrink: 0;
}
.showcase-acc-inline-link { font-size: 12px; }
.showcase-acc-chevron {
    color: var(--ink-400);
    font-size: 12px;
    transition: transform 0.15s;
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px;
}
.showcase-acc[open] > .showcase-acc-summary .showcase-acc-chevron {
    transform: rotate(180deg);
}
.showcase-acc-body {
    padding: 16px 18px;
}

/* Preview body: the iframe fills the body edge-to-edge (no inner
   padding — looks more like an actual preview window). */
.showcase-preview-acc .showcase-acc-body { display: none; }  /* unused container */
.showcase-preview-acc[open] .showcase-preview-frame {
    display: block;
}
.showcase-preview-frame {
    position: relative; width: 100%; height: 560px; background: #0b0f19;
}
.showcase-preview-frame iframe {
    width: 100%; height: 100%; border: 0; display: block;
}

.showcase-settings-form { display: contents; }

.showcase-field { display: block; }
.showcase-field > span {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--ink-700);
    margin-bottom: 6px;
}
.showcase-field input[type="text"] {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--ink-100);
    border-radius: 8px;
    font-size: 13px;
    color: var(--ink-900);
    background: #fff;
}
.showcase-field input[type="text"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.showcase-save-row {
    display: flex; align-items: center; gap: 12px;
    margin-top: 14px;
    padding: 0 2px;
    flex-wrap: wrap;
}

.showcase-modes { display: flex; flex-direction: column; gap: 12px; }
.showcase-mode {
    border: 1px solid var(--ink-100);
    border-radius: 10px;
    padding: 14px 16px;
    background: #fff;
}
.showcase-mode.is-locked { background: #fafafa; opacity: 0.92; }
.showcase-mode-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 10px;
}
.showcase-mode-title { font-size: 14px; font-weight: 600; color: var(--ink-900); }
.showcase-mode-sub { font-size: 12.5px; color: var(--ink-600); margin-top: 2px; }
.showcase-mode-badge {
    font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px;
    background: #eef2ff; color: #3730a3; text-transform: none; white-space: nowrap;
    border: 1px solid #c7d2fe;
}
.showcase-mode-badge.ok { background: #ecfdf5; color: #065f46; border-color: #a7f3d0; }
.showcase-mode-badge.warn { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.showcase-mode-badge.locked { background: #f5f5f7; color: var(--ink-500); border-color: var(--ink-100); }

.showcase-copy-row {
    display: flex; gap: 8px; align-items: stretch;
}
.showcase-copy-row input[type="text"],
.showcase-copy-row textarea {
    flex: 1; min-width: 0;
    border: 1.5px solid var(--ink-100); border-radius: 8px;
    padding: 9px 12px; font: inherit; font-size: 13px;
    font-family: "SFMono-Regular", Menlo, Consolas, monospace;
    color: var(--ink-900); background: #fff; resize: vertical;
}
.showcase-copy-row textarea { line-height: 1.45; min-height: 56px; }
.showcase-copy-btn { flex-shrink: 0; }
.showcase-mode-foot { font-size: 12px; color: var(--ink-500); margin: 8px 0 0; }
.showcase-mode-foot code { background: var(--ink-50, #f5f5f7); padding: 1px 5px; border-radius: 4px; }

.showcase-cname-row {
    display: flex; gap: 8px; align-items: stretch; margin-bottom: 10px;
}
.showcase-cname-row input[type="text"] {
    flex: 1; min-width: 0;
    border: 1.5px solid var(--ink-100); border-radius: 8px;
    padding: 9px 12px; font: inherit; font-size: 14px;
    color: var(--ink-900); background: #fff;
}
.showcase-cname-row input[type="text"]:focus {
    outline: none; border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.showcase-dns-help { margin-top: 4px; }
.showcase-dns-help > p { font-size: 12.5px; color: var(--ink-600); margin: 0 0 10px; }
.showcase-locked-copy {
    background: #fafafa; border: 1px dashed var(--ink-100);
    border-radius: 8px; padding: 12px 14px;
}
.showcase-locked-copy p { margin: 0; font-size: 13px; color: var(--ink-600); }

.showcase-events-subhead {
    font-size: 12px; font-weight: 600; color: var(--ink-700);
    text-transform: uppercase; letter-spacing: 0.4px;
    margin: 14px 0 8px;
}
.showcase-events-subhead:first-of-type { margin-top: 0; }
.showcase-events-subhead-muted { color: var(--ink-500); }
.showcase-events-list { list-style: none; padding: 0; margin: 0 0 8px; }
.showcase-events-list li {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; padding: 10px 12px; border: 1px solid var(--ink-100);
    border-radius: 8px; margin-bottom: 6px; background: #fff;
}
.showcase-events-list-muted li { background: #fafafa; }
.showcase-event-name {
    font-size: 13.5px; font-weight: 500; color: var(--ink-900); text-decoration: none;
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.showcase-event-name:hover { color: var(--accent); }
.showcase-event-date { font-size: 12px; color: var(--ink-500); white-space: nowrap; }

@media (max-width: 720px) {
    .showcase-summary { flex-direction: column; align-items: flex-start; }
    .showcase-preview-frame { height: 420px; }
    .showcase-copy-row, .showcase-cname-row { flex-direction: column; }
    .showcase-copy-btn { align-self: flex-start; }
}

/* ── Shared v3 account-menu dropdown (events list + studio manage
       headers + account shell). Lives here so every v3 screen loading
       studio.css gets the same chrome — no more inline duplicates. */
.events-user { position: relative; }
.events-avatar {
    width: 34px; height: 34px; border-radius: 12px; background: var(--ink-900);
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 12px; font-weight: 600; cursor: pointer;
    user-select: none; transition: box-shadow 0.12s;
    overflow: hidden;
}
.events-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.events-avatar:hover,
.events-user.is-open .events-avatar { box-shadow: 0 0 0 3px rgba(11, 15, 25, 0.1); }
.events-user-menu {
    position: absolute; top: calc(100% + 8px); right: 0; min-width: 240px;
    background: #fff; border: 1px solid var(--ink-100); border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.14); padding: 6px;
    display: none; z-index: 70;
}
.events-user.is-open .events-user-menu { display: block; }
.events-user-identity {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 12px 10px;
    border-bottom: 1px solid #f3f4f6; margin-bottom: 4px;
}
.events-user-photo {
    width: 36px; height: 36px; border-radius: 10px;
    object-fit: cover; flex-shrink: 0;
}
.events-user-text { min-width: 0; flex: 1; }
.events-user-name {
    font-size: 13px; font-weight: 600; color: var(--ink-900);
    line-height: 1.2;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.events-user-email {
    font-size: 11.5px; color: var(--ink-500);
    word-break: break-all; margin-top: 2px;
}
.events-user-link {
    display: block; padding: 8px 12px; font-size: 13.5px; color: var(--ink-900);
    text-decoration: none; border-radius: 6px; font-weight: 500;
}
.events-user-link:hover { background: #f5f5f7; }
.events-user-link.danger { color: #b91c1c; }
.events-user-link.danger:hover { background: #fef2f2; }

/* ── Account-menu plan + upgrade nudge ───────────────────────────
   Sits right under the identity row. Shows the org's current tier
   as a colour-coded pill and (when below Max) an upgrade card with
   a one-line value pitch. Visible at-a-glance plan status is the
   thing organisers asked for — the pill alone covers it; the card
   is the optional upsell. */
.events-user-plan {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 12px 6px;
    margin-bottom: 2px;
}
.events-user-plan-label {
    font-size: 11.5px; font-weight: 500;
    color: var(--ink-500);
    letter-spacing: 0.01em;
}
.events-user-plan-pill {
    display: inline-flex; align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; text-decoration: none;
    transition: transform 120ms ease;
}
.events-user-plan-pill:hover { transform: translateY(-1px); }
.events-user-plan-pill-free {
    background: #f3f4f6; color: var(--ink-700, #374151);
    border: 1px solid #e5e7eb;
}
.events-user-plan-pill-pro {
    background: #eef2ff; color: #3730a3;
    border: 1px solid #c7d2fe;
}
.events-user-plan-pill-max {
    background: #fef3c7; color: #92400e;
    border: 1px solid #fcd34d;
}
.events-user-plan-pill-enterprise {
    background: #0b0f19; color: #fff;
    border: 1px solid #0b0f19;
}

.events-user-upgrade {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    margin: 4px 8px 8px;
    padding: 10px 12px;
    background: linear-gradient(135deg, #eef2ff 0%, #f5f3ff 100%);
    border: 1px solid #c7d2fe;
    border-radius: 10px;
    text-decoration: none;
    transition: transform 120ms ease, box-shadow 120ms ease,
                border-color 120ms ease;
}
.events-user-upgrade:hover {
    transform: translateY(-1px);
    border-color: #a5b4fc;
    box-shadow: 0 6px 18px -8px rgba(79, 70, 229, 0.32);
}
.events-user-upgrade-text {
    display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.events-user-upgrade-text strong {
    font-size: 13px; font-weight: 600; color: #312e81;
}
.events-user-upgrade-sub {
    font-size: 11.5px; color: #4338ca; line-height: 1.35;
}
.events-user-upgrade-arrow {
    font-size: 16px; color: #4f46e5; flex-shrink: 0;
    transition: transform 160ms ease;
}
.events-user-upgrade:hover .events-user-upgrade-arrow {
    transform: translateX(2px);
}

/* Hairline between the plan/upgrade block and the link list below
   so the menu reads in three clear sections (identity / plan /
   actions) rather than one long chunk. */
.events-user-plan + .events-user-upgrade { margin-top: 0; }
.events-user-plan + .events-user-link,
.events-user-upgrade + .events-user-link {
    margin-top: 4px;
    padding-top: 8px;
    position: relative;
}
.events-user-plan + .events-user-link::before,
.events-user-upgrade + .events-user-link::before {
    content: '';
    position: absolute; top: 0; left: 8px; right: 8px;
    border-top: 1px solid #f3f4f6;
}
/* Locked links (Max-tier features for below-Max orgs): dim the label
   slightly but KEEP the link clickable — the route-level gate sends
   them to /v3/plans?from=hub, so the "Max" badge doubles as a
   discovery path into pricing. */
.events-user-link.is-locked {
    display: flex; align-items: center; justify-content: space-between;
    color: var(--ink-500);
}
.events-user-link.is-locked:hover { background: #f5f5f7; color: var(--ink-900); }
.events-user-link-badge,
.manage-nav-plan-badge {
    font-size: 9.5px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase;
    color: #3730a3; background: #eef2ff; border: 1px solid #c7d2fe;
    padding: 1px 6px; border-radius: 999px;
    margin-left: 8px; flex-shrink: 0;
}
.manage-nav-item.is-locked {
    display: flex; align-items: center; justify-content: space-between;
    color: var(--ink-500);
}
.manage-nav-item.is-locked:hover { color: var(--ink-900); }
/* Compound state — user is viewing the locked page they haven't
   unlocked yet (Event hub on a below-Max org). Without this rule the
   `.active` dark-pill bg stayed on but `.is-locked` grey text took
   over, giving a black pill with unreadable grey text (see screenshot
   in PR). Subtle `#f5f5f7` surface says "you're on this page" while
   the muted text + plan badge still telegraph "you don't own it yet". */
.manage-nav-item.active.is-locked {
    background: #f5f5f7;
    color: var(--ink-700);
    font-weight: 600;
}
.manage-nav-item.active.is-locked:hover { background: #ececef; color: var(--ink-900); }
/* Plan badge on the active-locked row needs a touch more contrast
   against the lighter background — keep the indigo but deepen it. */
.manage-nav-item.active.is-locked .manage-nav-plan-badge {
    background: #e0e7ff; color: #312e81; border-color: #a5b4fc;
}

/* "NEW" badge for recently-shipped nav items (e.g. AI Voice Support).
   Distinct from the Max-plan badge so users don't read it as a
   paywall — green denotes availability, not premium gating. */
.manage-nav-with-badge { gap: 8px; }
.manage-nav-new-badge {
    font-size: 9px; font-weight: 700; letter-spacing: 0.6px;
    text-transform: uppercase;
    color: #065f46;
    background: #d1fae5;
    border: 1px solid #6ee7b7;
    padding: 1px 6px; border-radius: 999px;
    flex-shrink: 0;
    animation: manage-new-pulse 2.8s ease-in-out infinite;
}
.manage-nav-item.active .manage-nav-new-badge {
    background: #a7f3d0; color: #064e3b; border-color: #34d399;
}
@keyframes manage-new-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
    50%      { box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.18); }
}
