/* ============================================================================
   Sign-in surface
   ----------------------------------------------------------------------------
   The centred card shell for login, signup, invite and onboarding, plus the
   few controls only those pages use (the slug input, the spinner, the wizard
   rail). Load house.css first: cards, buttons, fields, badges and modals all
   come from there, so the sign-in pages and the app cannot drift apart.

   Generated by subtracting every selector house.css already defines from
   design/whacl-ui.css. That file stays frozen as the design reference the
   static mockups in public/design load -- it is no longer served to anyone
   signing in.

   Some rules here belong to mockup-only components (message threads, channel
   cards) and are simply unused. Kept rather than hand-pruned: dropping a rule
   a live page turns out to need is a worse trade than a few KB.
   ========================================================================= */

/* ==========================================================================
   whacl-saas — design system for the NEW surfaces
   --------------------------------------------------------------------------
   Layer 1 (lines up to "NEW COMPONENTS") is lifted verbatim from biostone's
   public/_layout.php <style> block. Same tokens, same class names, same
   values — so anything built here drops into the existing app without a
   second design system growing beside the first.

   Layer 2 ("NEW COMPONENTS") is only what the new surfaces genuinely need
   and _layout.php does not already have: the signup/onboarding shell, the
   stepper, channel cards, the alert/failure family, richer empty states,
   usage meters, and the third message source.

   No CDN, no build step, no framework. Inter is self-hosted in production
   (see the @font-face block below — point it at your local /fonts/ copies);
   the mockups fall back to system-ui so they render without the binaries.
   ========================================================================== */

/* Production: uncomment and drop the .woff2 files in design/fonts/.
@font-face { font-family:'Inter'; font-style:normal; font-weight:400 800;
             font-display:swap; src:url('fonts/Inter.var.woff2') format('woff2'); }
*/

* { box-sizing: border-box; margin: 0; padding: 0; }
/* ---------- Cards ---------- */
.card-body { padding: 18px 20px; }
/* ---------- Buttons ---------- */
a.btn, a.btn:hover { color: #fff; }
.btn svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; flex-shrink: 0; }
/* A 15px mark inside a 13px/22px button reads small once the button itself
   is this big. */
.btn.lg svg { width: 17px; height: 17px; }
.btn.danger { background: #b91c1c; box-shadow: 0 6px 16px rgba(185,28,28,.25); }
.btn.danger:hover { background: #a41818; }
.btn.block { width: 100%; }
/* A slower, curved ease rather than .btn's own snappy .1s linear-feeling
   default -- right for a small icon button, too abrupt for something this
   size. Press scales down as well as dropping, which is what makes a big
   flat gradient button feel like it's actually being pushed rather than
   just re-tinted. */
.btn.lg {
    padding: 13px 22px; font-size: 14px; border-radius: 11px;
    transition: transform .28s cubic-bezier(.22,1,.36,1), box-shadow .28s cubic-bezier(.22,1,.36,1), filter .18s ease;
}
.btn.lg:hover { transform: translateY(-2px); filter: brightness(1.05); }
.btn.lg:active { transform: translateY(0) scale(.98); filter: brightness(.97); transition-duration: .1s; }
.btn[disabled], .btn.is-disabled {
    opacity: .45; cursor: not-allowed; transform: none !important; box-shadow: none;
}

.btn-link:hover { text-decoration: underline; }
/* ---------- Fields ---------- */
.field input[type=text], .field input[type=email], .field input[type=password],
.field input[type=tel], .field input[type=number], .field input[type=date],
.field textarea, .field select {
    width: 100%; padding: 11px 13px;
    background: #fafaf8;
    border: 1px solid rgba(0,0,0,.12);
    border-radius: 10px;
    color: #111; font-family: inherit; font-size: 13.5px; font-weight: 500;
    outline: none;
    transition: border-color .12s, box-shadow .12s, background .12s;
}
.field.err input, .field.err textarea { border-color: #b91c1c; background: rgba(220,38,38,.03); }
.field.err input:focus { box-shadow: 0 0 0 3px rgba(185,28,28,.1); }
.field-msg { font-size: 11.5px; font-weight: 600; margin-top: 6px; display: flex; align-items: center; gap: 5px; }
.field-msg svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.4; flex-shrink: 0; }
.field-msg.ok { color: #15803d; }
.field-msg.warn { color: #c2740c; }
.field-msg.bad { color: #b91c1c; }
.field-msg.load { color: rgba(0,0,0,.58); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; gap: 0; } }
/* ---------- Badges ---------- */
/* ---------- Tables ---------- */
table.list { width: 100%; border-collapse: collapse; }
/* ---------- Stats ---------- */
@media (max-width: 1100px) { .stat-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px)  { .stat-grid { grid-template-columns: 1fr; } }
/* ---------- Info tip ---------- */
/* ---------- Modal ---------- */
/* ==========================================================================
   NEW COMPONENTS — only what the new surfaces need
   ========================================================================== */

/* ---------- Auth / onboarding shell -------------------------------------
   A centred column on the warm canvas rather than the app's sidebar shell:
   at signup there is no tenant yet, so there is nothing to put in a sidebar.
   The brand mark sits above the card so the page reads as whacl's before
   the user has any account of their own. */
.auth-wrap {
    min-height: 100vh;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 40px 20px;
}
.auth-col { width: 100%; max-width: 440px; }
.auth-col.wide { max-width: 1120px; }
.brand {
    display: flex; align-items: center; gap: 10px;
    justify-content: center; margin-bottom: 24px;
}
.brand-name { font-weight: 800; font-size: 18px; letter-spacing: -0.01em; color: #111; }
.brand svg { flex-shrink: 0; }
.auth-card { padding: 30px 30px 26px; }
.auth-title { font-size: 21px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 6px; }
.auth-sub { font-size: 13px; color: rgba(0,0,0,.68); line-height: 1.55; margin-bottom: 22px; }
.auth-foot { text-align: center; font-size: 12.5px; color: rgba(0,0,0,.68); margin-top: 18px; }
.auth-foot a { font-weight: 600; color: #0B815A; }
.auth-foot a:hover { text-decoration: underline; }

/* ---------- Split auth: the pitch beside the form ----------
   Login only, and opt-in. Signup, invite and the password flows stay centred:
   somebody following an invite link or resetting a password has already
   decided, and a sales panel next to that form is noise.

   Two children, so this balances the same authOpen/authClose pair the centred
   layout uses -- .auth-pitch and .auth-col, no extra wrapper.

   On a phone the pitch is dropped rather than stacked above the form. Someone
   opening /login.php on a phone came to log in, and a screen of marketing to
   scroll past first is the wrong answer to that. */
/* Form left, dark panel right -- the same way round as setup, so signing up
   and then setting up do not mirror each other. authOpen() emits the pitch
   first so that a browser with no grid support still shows the form, hence
   the order swap here rather than in the markup. */
.auth-wrap.auth-split {
    display: grid;
    grid-template-columns: .95fr 1.05fr;
    align-items: stretch;
    padding: 0;
    max-width: none;
}
.auth-split /* Signup, login and setup all wear this panel, so it follows the same rule:
   the marketing site's warm ground, with the inbox window as the one dark
   object on it. It was near-black, which made arriving from whacl.com feel
   like arriving at a different product. */
.auth-pitch {
    position: relative; overflow: hidden;
    background: #eceae4;
    border-right: 1px solid rgba(0,0,0,.07);
    color: #111;
    display: flex; flex-direction: column; justify-content: center;
}
.auth-pitch::before {
    content: ''; position: absolute; inset: 0;
    background: radial-gradient(circle at 22% 6%, rgba(255,255,255,.9), transparent 55%);
    pointer-events: none;
}
.auth-pitch-inner {
    position: relative;
    padding: 56px clamp(28px, 4.4vw, 68px);
}
.pitch-brand { display: flex; align-items: center; gap: 13px; margin-bottom: 40px; }
.pitch-name { font-size: 21px; font-weight: 800; letter-spacing: -.02em; color: #111; line-height: 1.1; }
.pitch-kicker { font-size: 12px; font-weight: 600; color: rgba(0,0,0,.5); margin-top: 3px; }
.pitch-h {
    font-size: clamp(26px, 2.8vw, 36px); font-weight: 800;
    letter-spacing: -.03em; line-height: 1.14; color: #111;
    margin: 0 0 26px; max-width: 16ch; text-wrap: balance;
}
.pitch-h em { font-style: normal; color: #0B815A; }
.auth-pitch .wiz-art-win { margin-bottom: 30px; }
.pitch-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.pitch-list li {
    display: flex; align-items: center; gap: 13px;
    font-size: 13px; font-weight: 500; color: rgba(0,0,0,.72);
    animation: pitchIn .5s both;
}
.pitch-list li:nth-child(2) { animation-delay: .07s; }
.pitch-list li:nth-child(3) { animation-delay: .14s; }
.pitch-list li:nth-child(4) { animation-delay: .21s; }
@keyframes pitchIn { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .pitch-list li { animation: none; } }
.pitch-ic {
    width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0;
    background: #fff; border: 1px solid rgba(0,0,0,.06);
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.pitch-ic svg { width: 15px; height: 15px; fill: none; stroke: #0B815A; stroke-width: 1.8; }

@media (max-width: 900px) {
    .auth-wrap.auth-split { display: flex; padding: 40px 20px; }
    .auth-pitch { display: none; }
    .auth-split .auth-col { padding: 0; }
}
/* Slug preview: the input and the fixed ".whacl.com" tail read as one
   control, so the subdomain never looks like a free-text field the user
   could type a full domain into. */
/* Small inline spinner. Pure CSS — no icon font, no SVG animation. */
.spin {
    width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0;
    border: 2px solid rgba(0,0,0,.15); border-top-color: rgba(0,0,0,.68);
    animation: spin .7s linear infinite; display: inline-block;
}
.spin.on-dark { border-color: rgba(255,255,255,.3); border-top-color: #fff; }
.spin.lg { width: 20px; height: 20px; border-width: 2.5px; }
/* The subtraction that built this file from whacl-ui.css took the @keyframes
   line and left the `to` behind, so every .spin on the site was a static grey
   ring -- a "checking…" indicator that never moved, which reads as a page that
   hung rather than one that is working. */
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- End-of-flow message card -------------------------------------
   The request-received screen. Centred, with the icon above the title, so it
   reads as an answer rather than as another form to fill in. */
.auth-card.is-message { text-align: center; }
.auth-ico { margin: 0 auto 16px; background: rgba(22,163,74,.1); }
.auth-ico svg { stroke: #15803d; }

/* What happens next, numbered. A request form that ends in "thanks" and
   nothing else is why the first support email is always "did it work?". */
.auth-lines { text-align: left; margin: 4px 0 22px; }
.auth-line {
    display: flex; align-items: flex-start; gap: 11px;
    padding: 11px 0; border-bottom: 1px solid rgba(0,0,0,.06);
    font-size: 13px; line-height: 1.55; color: rgba(0,0,0,.65);
}
.auth-line:last-child { border-bottom: none; }
.auth-line b { color: #111; font-weight: 600; }
.auth-line .n {
    display: flex; align-items: center; justify-content: center;
    width: 21px; height: 21px; flex-shrink: 0; margin-top: 1px;
    border-radius: 50%; background: rgba(0,0,0,.06);
    font-size: 11px; font-weight: 700; color: rgba(0,0,0,.68);
}
.auth-note {
    font-size: 11.5px; line-height: 1.55; color: rgba(0,0,0,.58);
    margin-top: 14px; text-align: center;
}
.auth-note a { color: rgba(0,0,0,.6); font-weight: 600; }
.auth-note a:hover { text-decoration: underline; }
.signup-advanced { margin: -2px 0 18px; border-top: 1px solid rgba(0,0,0,.06); border-bottom: 1px solid rgba(0,0,0,.06); }
.signup-advanced summary { padding: 12px 0; cursor: pointer; list-style: none; font-size: 12px; font-weight: 650; color: rgba(0,0,0,.58); }
.signup-advanced summary::-webkit-details-marker { display: none; }
.signup-advanced summary::after { content: '+'; float: right; font-size: 16px; font-weight: 400; }
.signup-advanced[open] summary::after { content: '−'; }
.signup-advanced .field { margin: 2px 0 14px; }
/* ---------- Onboarding stepper -----------------------------------------
   Persistent and always visible: the wizard is resumable, so the user must
   be able to see at a glance how much is left and that their finished steps
   are saved. Vertical rail on desktop, a compact horizontal strip on phones
   (where vertical would eat the whole first screen). */
/* One card, not two boxes with a gap between them. Everything the wizard
   shows -- the top bar, the rail and the step content -- lives inside a
   single rounded shell with one shadow and one edge, the way a real
   product's setup flow reads (Convertico, Nexhire) rather than as
   components that happen to sit next to each other. */
.wiz {
    display: flex; flex-direction: column;
    background: #fff; border-radius: 30px; overflow: hidden;
    box-shadow: 0 40px 90px rgba(0,0,0,.14), 0 4px 14px rgba(0,0,0,.05);
}
/* A floor, not a viewport height: enough that the six-step rail is never
   taller than the panel beside it, without stretching the card to fill a
   window whose height the content has no use for. */
.wiz-body { display: flex; align-items: stretch; min-height: 640px; }
/* The form column. White, and the only thing on it is the step you are on --
   the seven-step rail that used to sit beside it moved to a three-phase crumb
   bar above the title, because a list of seven is a chore to read and the
   phase you are in is the only part of it anyone acts on. */
.wiz-crumbs {
    display: flex; align-items: center; gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 34px;
}
.wiz-crumb {
    display: inline-flex; align-items: center; gap: 9px;
    color: rgba(20,20,15,.46);
    font-size: 13.5px; font-weight: 600;
    text-decoration: none;
    border-radius: 100px;
    transition: color .18s;
}
a.wiz-crumb:hover { color: #14140F; }
/* The number is the state. Ahead of you it is a hairline ring, on you it is
   the filled dark pill, behind you it is a green tick -- one mark per state,
   so nothing is saying the same thing twice. */
.wiz-crumb-n {
    width: 22px; height: 22px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    border: 1.5px solid rgba(20,20,15,.16);
    font-size: 11.5px; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.wiz-crumb-l { white-space: nowrap; }
.wiz-crumb-n svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.wiz-crumb.current { color: #14140F; }
.wiz-crumb.current .wiz-crumb-n { background: #14140F; border-color: #14140F; color: #fff; }
.wiz-crumb.done { color: rgba(20,20,15,.62); }
.wiz-crumb.done .wiz-crumb-n { border-color: rgba(11,129,90,.4); color: #0B815A; background: rgba(11,129,90,.08); }
.wiz-crumb-sep { display: inline-flex; color: rgba(20,20,15,.2); }
.wiz-crumb-sep svg { width: 14px; height: 14px; }

/* ---------------------------------------------------------------- the art
   The dark half of the split. It holds the two things the form cannot show
   about itself: what the AI has actually been told so far, and a stand-in for
   the inbox all of this is building towards. Hidden below 980px, where there
   is no room for a second column and the form is the whole job. */
/* The other half of the split.
   It was near-black with a green radial behind it, which is not what whacl
   looks like anywhere else: the marketing site is #eceae4 warm grey with #111
   for its dark blocks and green used only as an accent. A dark slab beside a
   white form read as a different product. This is the site's ground, with the
   inbox window as the one dark object on it -- the same relationship the
   homepage has between its body and its footer. */
.wiz-art {
    width: 44%; max-width: 520px; flex-shrink: 0;
    position: relative; overflow: hidden;
    background: #eceae4;
    border-left: 1px solid rgba(0,0,0,.07);
    color: #111;
    display: none;
}
.wiz-art-glow {
    position: absolute; inset: 0;
    background: radial-gradient(circle at 80% 8%, rgba(255,255,255,.85), transparent 52%);
    pointer-events: none;
}
.wiz-art-inner {
    position: relative;
    height: 100%;
    padding: 40px 34px 26px;
    display: flex; flex-direction: column;
}

/* The window is the dark object. Enough chrome to read as the product,
   never enough to pass as a screenshot of a real inbox. */
.wiz-art-win {
    border-radius: 16px; overflow: hidden;
    background: #111;
    box-shadow: 0 20px 44px rgba(17,17,17,.18);
}
.wiz-art-bar {
    display: flex; align-items: center; gap: 6px;
    padding: 11px 13px;
    border-bottom: 1px solid rgba(255,255,255,.08);
}
.wiz-art-dot { width: 9px; height: 9px; border-radius: 50%; }
.wiz-art-dot.r { background: #ff5f57; }
.wiz-art-dot.y { background: #febc2e; }
.wiz-art-dot.g { background: #28c840; }
.wiz-art-win-ttl {
    margin-left: 8px;
    font-size: 11px; font-weight: 600;
    color: rgba(255,255,255,.5);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wiz-art-chat { padding: 16px 14px; display: flex; flex-direction: column; gap: 9px; }
.wiz-art-msg {
    max-width: 84%;
    padding: 9px 12px;
    font-size: 12.5px; line-height: 1.5;
}
.wiz-art-msg.them {
    align-self: flex-start;
    background: rgba(255,255,255,.1);
    color: rgba(255,255,255,.85);
    border-radius: 4px 14px 14px 14px;
}
.wiz-art-msg.us {
    align-self: flex-end;
    background: #0B815A;
    color: #fff;
    border-radius: 14px 4px 14px 14px;
}

/* On a light ground the knowledge card and the identity foot need no dark
   re-toning at all -- they are the components as house.css draws them, which
   is the point of not having a second palette. */
.wiz-art .wiz-knowledge {
    background: #fff;
    border: 1px solid rgba(0,0,0,.07);
    margin: 22px 0 0;
}
.wiz-art .wiz-rail-foot { margin-top: auto; }
@media (min-width: 980px) { .wiz-art { display: block; } }
.wiz-progress { height: 5px; border-radius: 3px; background: rgba(0,0,0,.08); overflow: hidden; margin-bottom: 18px; }
.wiz-progress i { display: block; height: 100%; border-radius: 3px; background: #0B815A; transition: width .3s; }
/* "What the AI knows" — every field a step has filled in so far, read live
   off the tenant's own data rather than off which steps are marked done. A
   step can be marked done with nothing useful in it (skipped), so the two
   are tracked separately: the rail says how far, this says how much the AI
   actually has to work with. */
.wiz-knowledge { position: relative; margin: 26px 0 20px; border-radius: 14px; border: none; background: #f2f1ec; padding: 16px 17px 13px; }
.wiz-knowledge-head { font-size: 10.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: rgba(0,0,0,.58); margin-bottom: 12px; }
.wiz-knowledge-item { display: flex; align-items: flex-start; gap: 10px; padding: 6px 0; }
.wiz-knowledge-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; margin-top: 6px; background: rgba(0,0,0,.14); transition: background .2s, box-shadow .2s; }
.wiz-knowledge-dot.on { background: #0B815A; box-shadow: 0 0 0 3px rgba(11,129,90,.16); }
.wiz-knowledge-lab { display: block; font-size: 10.5px; color: rgba(0,0,0,.58); font-weight: 600; }
.wiz-knowledge-val { display: block; font-size: 12.5px; line-height: 1.45; margin-top: 2px; font-weight: 500; color: rgba(0,0,0,.58); }
.wiz-knowledge-val.on { font-weight: 600; color: #111; }
/* Who is setting this up, pinned to the bottom of the rail the way an app
   sidebar names the signed-in person -- setup is the one screen in the
   product that happens before there is a real sidebar to put this in. */
/* A tile, not a rule with text under it: the rail's own footer needs to read
   as one object the way the sidebar's does in the real app. margin-top:auto
   pins it to the bottom however tall the step list happens to be. */
.wiz-rail-foot {
    margin-top: auto; display: flex; align-items: center; gap: 10px;
    padding: 10px 12px; border-radius: 13px;
    background: #fff; border: 1px solid rgba(0,0,0,.07);
    box-shadow: 0 2px 8px rgba(0,0,0,.04);
}
.wiz-rail-av {
    width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
    background: linear-gradient(150deg, #a9d8c5, #4aa385); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700;
}
.wiz-rail-who { min-width: 0; flex: 1; }
.wiz-rail-nm { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 700; color: #111; }
.wiz-rail-em { font-size: 11.5px; color: rgba(0,0,0,.58); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* A reading column, not a full-bleed panel. Past ~640px the eye loses the
   start of the next line, and every step here is prose plus one control --
   the same measure the .wiz-lede already capped itself to, applied to the
   whole step instead of just its first paragraph. */
.wiz-panel {
    flex: 1; min-width: 0; padding: 46px 56px 56px;
    display: flex; flex-direction: column; justify-content: flex-start;
}
.wiz-panel > * { width: 100%; max-width: 640px; }
/* connect.php wearing the wizard's chrome without its rail. Meta's SDK
   allowlist means connecting cannot happen inside onboarding.php itself (see
   that file's header), so the page borrows the card instead of the flow --
   and with no rail beside it the lone panel would otherwise sit hard against
   the left edge where the rail used to be. */
.wiz-body.solo { min-height: 0; }
.wiz-body.solo .wiz-panel { align-items: center; padding: 44px 40px 48px; }
/* The step arrives rather than blinking into place. Every step is a full
   server render, so this is a page-load animation, not a transition -- and
   it is the whole of what makes moving through setup feel continuous. */
@keyframes wizIn { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
.wiz-panel { animation: wizIn .34s cubic-bezier(.2, .7, .3, 1) both; }
.wiz-eyebrow { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: #666660; margin-bottom: 10px; }
/* Bigger and tighter than a section heading, because it is the only thing on
   the step that has to be read before anything else. #14140F rather than #111:
   a warm-black on a warm ground, matching the rail's own ink. */
.wiz-title { font-size: 29px; font-weight: 800; letter-spacing: -0.035em; line-height: 1.06; color: #14140F; margin-bottom: 14px; }
.wiz-lede { font-size: 14px; color: rgba(0,0,0,.68); line-height: 1.62; margin-bottom: 24px; }

/* A labelled group of cards: heading, one line saying what it is, then the
   cards. The step used to run title straight into controls, so a step with
   two unrelated groups in it (channels, or the go-live summary) had nothing
   naming either. Mirrors .adp-section-ttl on the ad pages. */
.wiz-sec { margin-bottom: 26px; }
.wiz-sec:last-child { margin-bottom: 0; }
.wiz-sec-ttl { font-size: 13px; font-weight: 700; color: #111; margin-bottom: 3px; }
.wiz-sec-sub { font-size: 12.5px; color: rgba(0,0,0,.58); line-height: 1.55; margin-bottom: 12px; }

/* ---- the card -----------------------------------------------------------
   One component for every "here is a thing, here is its state, here is the
   one action on it" row in setup: the connected number, each channel, an
   uploaded price list, the go-live summary. Before this there were five
   different boxes (.chan, .alert, .wiz-note-card, .summary-line, .ds-row)
   drawing the same idea, and they had already drifted apart.

   Filled warm tile, no border, 14px radius -- the shape the stat and chart
   tiles on the ad pages use, which is this product's own look rather than
   the hairline-bordered card every SaaS template ships with. */
.wiz-card {
    display: flex; align-items: flex-start; gap: 13px;
    padding: 16px 18px; border-radius: 14px;
    background: #f7f6f3; border: 1.5px solid transparent;
    transition: background .15s, border-color .15s, transform .15s, box-shadow .15s;
}
.wiz-card + .wiz-card { margin-top: 10px; }
.wiz-card.is-link:hover { background: #f2f1ec; transform: translateY(-1px); box-shadow: 0 8px 20px rgba(0,0,0,.06); }
/* Waiting on them, not broken -- amber, and the only card in setup that
   carries a border, because it is the one they must not scroll past. */
.wiz-card.is-warn { background: rgba(224,138,30,.06); border-color: rgba(224,138,30,.32); }
.wiz-card.is-bad  { background: rgba(220,38,38,.04); border-color: rgba(185,28,28,.3); }
/* Not-yet-connected is still a real row, so it gets the same filled tile as
   every other one. It used to be drawn as a dashed outline, which is the
   convention for a drop target or a placeholder -- an Instagram account that
   simply is not connected yet is neither, and beside the solid tiles above it
   the dashes read as something half-built rather than something optional. */
.wiz-card.is-off  { background: #f7f6f3; border-color: transparent; }
/* The dashes did carry the state at a glance, though, and the badge alone is
   small print. The brand mark does that job better: full colour once the
   channel is live, greyed while it is not, so the row reads connected or not
   from across the screen without anything being drawn as broken. */
.wiz-card.is-off .chan-logo {
    filter: grayscale(1); opacity: .45;
    box-shadow: none;
    transition: filter .18s ease, opacity .18s ease;
}
/* .wiz-card has always declared transform and box-shadow in its transition,
   with no rule anywhere that changed either -- the hover this was written for
   was never added. These are the rows that carry a Connect button, so they
   are the ones worth answering to the pointer; the mark coming up to full
   colour previews what connecting does. Mirrors .chan's own hover. */
.wiz-card.is-off:hover { background: #f4f2ee; }
.wiz-card.is-off:hover .chan-logo { filter: grayscale(.15); opacity: .9; }

.wiz-card-ico {
    width: 40px; height: 40px; border-radius: 12px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,.07);
}
.wiz-card-ico svg { width: 21px; height: 21px; }
.wiz-card-main { flex: 1; min-width: 0; }
.wiz-card-ttl { font-size: 13.5px; font-weight: 700; color: #111; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wiz-card-sub { font-size: 12.5px; color: rgba(0,0,0,.68); margin-top: 3px; line-height: 1.55; }
.wiz-card-sub b { color: rgba(0,0,0,.78); font-weight: 600; }
.wiz-card-side { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* The strip inside the card that names the problem. Inside, not under: a
   message about this card that sits outside it is a message about the page. */
.wiz-card-note {
    display: flex; align-items: flex-start; gap: 8px;
    margin: 13px 0 0; padding: 10px 12px; border-radius: 10px;
    background: rgba(224,138,30,.1); color: #c2740c;
    font-size: 12.5px; font-weight: 600; line-height: 1.5;
}
.wiz-card-note svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; flex-shrink: 0; margin-top: 1px; }
.wiz-card-note.ok { background: rgba(22,163,74,.1); color: #15803d; }

/* A card that opens to hold a form -- the register-PIN step, where the
   action needs two fields rather than one button. */
.wiz-card-form { width: 100%; margin-top: 13px; padding-top: 13px; border-top: 1px solid rgba(0,0,0,.07); }
.wiz-card-row { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.wiz-card-col { flex-direction: column; align-items: stretch; }

@media (max-width: 560px) {
    .wiz-card { flex-wrap: wrap; }
    .wiz-card-side { width: 100%; justify-content: flex-start; }
}
.wiz-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    margin-top: 30px; padding-top: 24px; border-top: 1px solid rgba(0,0,0,.06);
    flex-wrap: wrap;
}
.wiz-saved { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: #15803d; }
.wiz-saved svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.4; }
@media (max-width: 980px) {
    .wiz-body { flex-direction: column; }
    .wiz-rail { width: auto; border-right: none; border-bottom: 1px solid rgba(0,0,0,.06); padding: 24px 24px 18px; }
    .steps { flex-direction: row; overflow-x: auto; gap: 6px; padding-bottom: 4px; }
    /* Laid side by side, the accent bar moves from the left edge to underneath
       and the divider goes: a hairline under every step is a divider between
       stacked rows, and between side-by-side ones it is just a line under the
       whole strip. The tick and dot go too -- at this width the underline
       already says which step you are on, and the strip has to stay short. */
    .step {
        width: auto; flex-shrink: 0; padding: 8px 12px;
        border-left: none; border-bottom: 2px solid transparent;
    }
    .step:last-child { border-bottom: 2px solid transparent; }
    .step.current { border-bottom-color: #0B815A; }
    .step-mark { display: none; }
    /* .step.current .step-note is 0,2,0 and would otherwise win over a bare
       .step-note here, putting the notes back into the phone strip. */
    .step-note, .step.current .step-note, .wiz-rail-head { display: none; }
    .wiz-knowledge, .wiz-rail-foot { display: none; }
    .wiz-panel { padding: 26px 22px; justify-content: flex-start; }
    .wiz-title { font-size: 24px; }
}
/* ---------- Channel card ------------------------------------------------
   One row per channel wherever channels appear: onboarding, Settings'
   connection panel, superadmin tenant detail. Status is carried by both a
   dot and a word — colour alone is never the only signal. */
.chan {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 16px 18px; border-radius: 14px;
    border: 1px solid rgba(0,0,0,.08); background: #fff;
}
.chan + .chan { margin-top: 12px; }
.chan-logo {
    width: 44px; height: 44px; border-radius: 13px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 4px 10px rgba(0,0,0,.14);
}
.chan-logo svg { width: 24px; height: 24px; }
/* The tile is the brand colour, so the mark on it is white. Stated rather
   than baked into the glyph's own fill, because the same glyph is also used
   on a brand-coloured button where it follows the button's text instead. */
.chan-logo { color: #fff; }
/* Real brand marks, in each brand's own colour, rather than the app's tinted
   outline icons -- these three logos are recognised on sight, and a
   house-coloured stroke version of them reads as "not quite the real one". */
.chan-logo.wa { background: linear-gradient(155deg,#31d572,#0aa955); }
.chan-logo.ig { background: radial-gradient(circle at 30% 112%, #ffd521 0%, #fbc03e 14%, #f6552d 34%, #dd2a7b 62%, #9d3cc7 82%, #5a52d5 100%); }
.chan-logo.ms { background: linear-gradient(135deg,#00b2ff 0%,#2f6cff 45%,#9a4dff 100%); }
.chan-main { flex: 1; min-width: 0; }
.chan-name { font-size: 14.5px; font-weight: 700; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.chan-meta { font-size: 12.5px; color: rgba(0,0,0,.68); margin-top: 4px; line-height: 1.55; }
.chan-meta b { color: rgba(0,0,0,.75); font-weight: 600; }
.chan-side { display: flex; align-items: center; gap: 8px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.chan.is-off { background: #fafaf8; border-style: dashed; }
.chan.is-bad { border-color: rgba(185,28,28,.35); background: rgba(220,38,38,.02); }
.chan.is-warn { border-color: rgba(224,138,30,.4); background: rgba(224,138,30,.03); }
.chan { transition: box-shadow .18s ease, transform .18s ease; }
.chan:not(.is-off):hover { box-shadow: 0 10px 26px rgba(0,0,0,.07); transform: translateY(-1px); }
@media (max-width: 560px) {
    .chan { flex-wrap: wrap; }
    .chan-side { width: 100%; justify-content: flex-start; }
}
/* Status dot + word, used inline anywhere a channel state is named. */
.st { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; white-space: nowrap; }
.st i { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.st.ok    { color: #15803d; }
.st.ok i    { background: #16a34a; box-shadow: 0 0 0 3px rgba(22,163,74,.15); }
.st.warn  { color: #c2740c; }
.st.warn i  { background: #e08a1e; box-shadow: 0 0 0 3px rgba(224,138,30,.16); }
.st.bad   { color: #b91c1c; }
.st.bad i   { background: #dc2626; box-shadow: 0 0 0 3px rgba(220,38,38,.14); }
.st.off   { color: rgba(0,0,0,.58); }
.st.off i { background: rgba(0,0,0,.3); box-shadow: 0 0 0 3px rgba(0,0,0,.07); }
/* ---------- Alert / failure states --------------------------------------
   The brief is explicit that these are product surface, not a red toast:
   every one states what happened, what it means for the business right now,
   and the one action that fixes it. Same anatomy every time so a client
   learns to read them.  */

/* Full-width banner variant, for the top of a page or the app shell. */
.banner {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 18px; font-size: 12.5px; font-weight: 600;
}
.banner svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; flex-shrink: 0; }
.banner .sp { flex: 1; }
.banner.danger { background: #b91c1c; color: #fff; }
.banner.warn { background: #e08a1e; color: #fff; }
.banner a { color: inherit; text-decoration: underline; font-weight: 700; }
/* ---------- Empty states ------------------------------------------------
   A new tenant's first week is all empty screens, so these say what will
   appear here and what to do next — never just "No data". */
/* ---------- Usage meter -------------------------------------------------
   Plan caps are shown as a bar plus the two numbers, because "812 of 1,000"
   is the part a client acts on and a bar alone can't be read precisely. */
.meter { height: 8px; border-radius: 5px; background: rgba(0,0,0,.07); overflow: hidden; }
.meter i { display: block; height: 100%; border-radius: 5px; background: #0B815A; transition: width .3s; }
.meter.warn i { background: #e08a1e; }
.meter.bad i  { background: #b91c1c; }
.meter-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.meter-lab { font-size: 12.5px; font-weight: 600; color: rgba(0,0,0,.6); }
.meter-val { font-size: 12.5px; font-weight: 700; color: #111; }
.meter-foot { font-size: 11.5px; color: rgba(0,0,0,.58); margin-top: 7px; }
.meter-block + .meter-block { margin-top: 18px; }
/* ---------- Message bubbles (three sources) -----------------------------
   Biostone has two sources: AI and You. Coexistence adds a third — the
   owner replying from the WhatsApp Business app on their phone — and the
   three must never be confusable, so each differs in side, fill AND label:
     customer  left,  white, plain
     AI        right, green tint, solid
     you       right, dark (the dashboard's own voice)
     phone     right, dashed outline — visibly "not sent from here"
   Bubble text uses dir="auto" in the markup: customer messages arrive in
   Arabic and Darija and must lay out RTL while the UI around them stays LTR. */
.thread { display: flex; flex-direction: column; gap: 14px; padding: 20px; }
.msg { display: flex; flex-direction: column; max-width: 82%; }
.msg.out { align-self: flex-end; align-items: flex-end; }
.msg.in  { align-self: flex-start; align-items: flex-start; }
.msg-src {
    display: flex; align-items: center; gap: 5px; margin-bottom: 5px;
    font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}
.msg-src svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2.2; }
.bubble {
    padding: 10px 13px; border-radius: 14px;
    font-size: 13px; line-height: 1.5; word-break: break-word;
    box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.bubble[dir=rtl], .bubble:dir(rtl) { text-align: right; }
.msg-time { font-size: 10.5px; color: rgba(0,0,0,.58); margin-top: 4px; }
.msg.customer .msg-src { color: rgba(0,0,0,.58); }
.msg.customer .bubble { background: #fff; color: #222; border-bottom-left-radius: 4px; }
.msg.ai .msg-src { color: rgba(0,0,0,.55); }
/* Dark, not green-tinted -- ai-training's own sandbox draws its AI bubble
   as solid ink, and this now matches it rather than reading as a second,
   WhatsApp-flavoured version of the same feature. */
.msg.ai .bubble { background: #111; color: #fff; border-bottom-right-radius: 4px; }
.msg.you .msg-src { color: rgba(0,0,0,.6); }
.msg.you .bubble { background: #111; color: #fff; border-bottom-right-radius: 5px; }
.msg.phone .msg-src { color: #7c5cd6; }
.msg.phone .bubble {
    background: rgba(124,92,214,.06); color: #2b2340;
    border: 1.5px dashed rgba(124,92,214,.55);
    border-bottom-right-radius: 5px;
}
/* Legend that ships above the thread the first time a phone-sent message
   appears — three sources is one more than anyone expects. */
.src-legend { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 11px 18px; border-bottom: 1px solid rgba(0,0,0,.06); font-size: 11.5px; font-weight: 600; color: rgba(0,0,0,.68); }
.src-legend span { display: flex; align-items: center; gap: 6px; }
.src-key { width: 15px; height: 15px; border-radius: 5px; flex-shrink: 0; }
.src-key.ai { background: rgba(11,129,90,.14); border: 1px solid rgba(11,129,90,.35); }
.src-key.you { background: #111; }
.src-key.phone { background: rgba(124,92,214,.08); border: 1.5px dashed rgba(124,92,214,.6); }
@media (max-width: 700px) { .msg { max-width: 86%; } .thread { padding: 14px; } }
/* ---------- App shell ---------------------------------------------------
   Verbatim from _layout.php. Present here only so the tenant-dashboard
   additions can be seen inside the real chrome they'll live in — when these
   screens become PHP they inherit it from ui_header() and this block goes. */
body.app { display: flex; min-height: 100vh; }
.sidebar {
    width: 236px; min-width: 236px;
    background: rgba(255,255,255,.5);
    backdrop-filter: blur(22px) saturate(180%); -webkit-backdrop-filter: blur(22px) saturate(180%);
    border-right: 1px solid rgba(255,255,255,.6);
    box-shadow: 4px 0 24px rgba(0,0,0,.05);
    display: flex; flex-direction: column; padding: 22px 14px;
    position: fixed; left: 0; top: 0; bottom: 0; height: 100vh; overflow-y: auto; z-index: 10;
}
.sidebar .brand { justify-content: flex-start; gap: 10px; padding: 6px 10px 26px 8px; margin: 0; }
.nav { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.nav a {
    display: flex; align-items: center; gap: 12px;
    padding: 9px 14px; border-radius: 9px;
    font-size: 13.5px; font-weight: 500; color: rgba(0,0,0,.65);
    transition: background .12s, color .12s;
}
.nav a svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; flex-shrink: 0; }
.nav a:hover { background: rgba(255,255,255,.65); color: #111; }
.nav a.active { background: #111; color: #fff; box-shadow: 0 6px 16px rgba(0,0,0,.22); }

.side-foot {
    margin-top: 16px; display: flex; align-items: center; gap: 10px;
    padding: 12px 10px 4px; border-top: 1px solid rgba(255,255,255,.6);
}
.side-foot .avatar {
    width: 32px; height: 32px; border-radius: 50%; background: #e5e3dd;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 13px; color: #333; flex-shrink: 0;
}
.side-foot .nm { font-size: 12.5px; font-weight: 600; color: #111; }
.side-foot .rl { font-size: 11px; color: rgba(0,0,0,.58); }
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; margin-left: 236px; }
.topbar {
    position: sticky; top: 0; z-index: 5;
    display: flex; align-items: center; justify-content: space-between; gap: 18px;
    min-height: 84px; padding: 16px 32px;
    background: rgba(255,255,255,.45);
    backdrop-filter: blur(28px) saturate(200%); -webkit-backdrop-filter: blur(28px) saturate(200%);
    border-bottom: 1px solid rgba(255,255,255,.6);
    box-shadow: 0 8px 24px rgba(0,0,0,.06);
}
.page-title { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }
.top-right { display: flex; align-items: center; gap: 14px; }
.content { padding: 28px 32px 44px; flex: 1; display: flex; flex-direction: column; gap: 24px; }
.ai-status { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: rgba(0,0,0,.6); white-space: nowrap; padding: 6px 11px; border-radius: 9px; }
.ai-status:hover { background: rgba(255,255,255,.7); }
.ai-status .dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }
.ai-status.on .dot { background: #16a34a; box-shadow: 0 0 0 3px rgba(22,163,74,.15); }
/* Connection pill in the topbar (spec 2.1) — persistent, because a client
   who doesn't know their number is down finds out from an angry customer.
   It changes shape, not just colour, when something is wrong. */
.conn-pill {
    display: flex; align-items: center; gap: 7px;
    padding: 7px 12px; border-radius: 9px; cursor: pointer;
    font-size: 12.5px; font-weight: 600;
    background: rgba(255,255,255,.6); border: 1px solid rgba(255,255,255,.7); color: rgba(0,0,0,.6);
}
.conn-pill:hover { background: #fff; }
.conn-pill svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; }
.conn-pill.warn { background: rgba(224,138,30,.14); border-color: rgba(224,138,30,.35); color: #c2740c; }
.conn-pill.bad  { background: rgba(220,38,38,.12); border-color: rgba(220,38,38,.35); color: #b91c1c; }
@media (max-width: 820px) {
    .sidebar { width: 68px; min-width: 68px; padding: 22px 10px; }
    .main { margin-left: 68px; }
    .brand-name, .nav a span, .side-foot .who { display: none; }
    .nav a { justify-content: center; padding: 10px; }
    .sidebar .brand { justify-content: center; padding-left: 0; padding-right: 0; }
    .side-foot { justify-content: center; }
    .content { padding: 20px 16px 40px; }
    .topbar { padding: 14px 16px; min-height: 68px; }
}
/* ---------- Misc layout helpers ---------- */
.stack { display: flex; flex-direction: column; gap: 18px; }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.grow { flex: 1; min-width: 0; }
.sep { height: 1px; background: rgba(0,0,0,.06); margin: 18px 0; }
.kv { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; font-size: 13px; padding: 7px 0; }
.kv dt { color: rgba(0,0,0,.68); font-weight: 500; }
.kv dd { font-weight: 600; color: #111; text-align: right; }
/* Toggle switch — AI on/off, per-channel enable. */
.sw { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }

/* Dropzone — Step 2's knowledge upload. Block and positioned because the
   whole box is a <label> with the file input laid over it: the picker then
   works with no JavaScript, and the input itself never has to be seen. */
.drop {
    display: block; position: relative;
    border: 1.5px dashed rgba(0,0,0,.2); border-radius: 14px; background: #fafaf8;
    padding: 30px 22px; text-align: center; cursor: pointer;
    transition: border-color .12s, background .12s;
}
.drop:hover { border-color: #0B815A; background: rgba(11,129,90,.03); }
.drop svg { width: 26px; height: 26px; fill: none; stroke: rgba(0,0,0,.35); stroke-width: 1.7; margin-bottom: 10px; }
.drop-ttl { font-size: 13.5px; font-weight: 700; }
.drop-txt { font-size: 12px; color: rgba(0,0,0,.58); margin-top: 5px; }
/* Tabs used on the demo pages to show several states of one screen without
   inventing a navigation pattern that isn't in the spec. Mockup furniture —
   drop it when porting to PHP. */
.demo-bar {
    position: sticky; top: 0; z-index: 60;
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 9px 16px; background: #111; color: #fff;
}
.demo-bar b { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; opacity: .55; }
.demo-bar button {
    padding: 6px 12px; border-radius: 8px; border: 1px solid rgba(255,255,255,.2);
    background: none; color: rgba(255,255,255,.7);
    font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.demo-bar button:hover { background: rgba(255,255,255,.1); color: #fff; }
.demo-bar button.on { background: #fff; color: #111; border-color: #fff; }
.demo-bar a { margin-left: auto; color: rgba(255,255,255,.6); font-size: 12px; font-weight: 600; }
.demo-bar a:hover { color: #fff; }
[hidden] { display: none !important; }


/* ---- setup wizard ------------------------------------------------------
   onboarding.php. The rail, the panel and the stepper above are the design's
   own components and are reused here rather than restyled -- what follows is
   only what the six steps need on top of them.

   What used to be here was a second, plainer wizard: a horizontal stepper and
   its own .wiz, .wiz-title and .wiz-foot, defined *below* the rail versions in
   this same file and therefore silently overriding them. Two designs for one
   screen, one of them winning by line number. The page follows the rail now,
   and the duplicates are gone. */

/* A card on the canvas, not a full-bleed page. This was the other way round,
   on the reasoning that setup should read as the product's own screen -- but
   stretched to the viewport the wizard has to fill a height its content does
   not have, and the rail ended up with a band of empty warm grey under "what
   the AI knows" on every step. Sized to its content and centred, the same
   screen has no dead space in it at any window height. */
/* flex-start, not the centring .auth-wrap uses for the sign-in card. The
   wizard is taller than a short window, and a centred flex child that
   overflows its container pushes its own top edge above the scroll origin --
   the header and the first steps become unreachable at any scroll position.
   The sign-in card is short enough never to hit this; setup is not. */
.wiz-wrap { justify-content: flex-start; padding: 32px 24px; }

/* A slim strip, not a hero header: logo + a divider + the workspace name on
   the left, one clear way out on the right. */
.wiz-top {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; padding: 16px 32px; border-bottom: 1px solid rgba(0,0,0,.08);
}
.wiz-top .brand { margin: 0; justify-content: flex-start; }
.wiz-top .brand::after {
    content: ''; width: 1px; height: 18px; margin-left: 4px;
    background: rgba(0,0,0,.12); display: inline-block;
}
.wiz-top-right { display: flex; align-items: center; gap: 10px; }
/* "Back to dashboard", styled as the one exit rather than a plain text link
   -- a pill with a keyboard hint, the way a real app names its escape hatch. */
.wiz-back {
    display: flex; align-items: center; gap: 8px;
    padding: 7px 8px 7px 12px; border-radius: 9px;
    border: 1px solid rgba(0,0,0,.1); background: #fff;
    font-size: 12.5px; font-weight: 600; color: rgba(0,0,0,.7);
}
.wiz-back:hover { border-color: rgba(0,0,0,.25); color: #111; }
.wiz-back svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.2; }

/* A step you cannot open yet is a <span>, and .step's own cursor:pointer would
   promise a click that does nothing. Jumping ahead is refused on purpose --
   "Go live" before a number is connected is a summary of nothing. */
span.step { cursor: default; }

/* A quiet framed list -- "what happens when you click", and the summary on the
   last step. Not a .card: it sits inside one, and a second shadowed white box
   inside a white box reads as a stack of unrelated things. */
.wiz-note-card {
    border: 1px solid rgba(0,0,0,.08); border-radius: 14px; background: #fafaf8;
    padding: 6px 20px; margin-bottom: 20px;
}
.summary-line {
    display: flex; align-items: center; gap: 12px;
    padding: 13px 0; border-bottom: 1px solid rgba(0,0,0,.06);
    font-size: 13px; line-height: 1.55; color: rgba(0,0,0,.7);
}
.summary-line:last-child { border-bottom: none; }
.summary-line svg { width: 17px; height: 17px; flex-shrink: 0; align-self: flex-start; margin-top: 2px; }
.summary-line b { color: #111; font-weight: 600; }
.summary-line .dim { color: rgba(0,0,0,.68); }

.wiz-note { font-size: 12.5px; line-height: 1.65; color: rgba(0,0,0,.68); margin-top: 16px; }
.wiz-warn { color: #b91c1c; }

/* WhatsApp green, on the button that connects a WhatsApp number.
   It was Facebook blue, which made a WhatsApp screen look like the wrong
   screen; it was then dark like the Meta buttons, which made connecting a
   phone number look like the same act as connecting a Page. It is neither:
   the channel is WhatsApp, so the button is WhatsApp's colour, and the line
   underneath is where the Facebook sign-in gets explained. Same size, same
   left-aligned mark-then-label as the Meta buttons. */
.btn-wa { background: linear-gradient(155deg,#31d572,#0aa955); box-shadow: 0 6px 16px rgba(10,169,85,.28); }
.btn-wa:hover { background: linear-gradient(155deg,#2bc668,#09994c); }
/* The icon block below keeps its own sizing: the spinner swap uses it. */
/* connect.php swaps the Facebook mark for a spinner while FB.login is
   working, so the button itself says something instead of only the text
   line below it. Success navigates away before it would ever revert --
   only a cancel needs to put the mark back. */
.btn-meta-icon { position: relative; display: inline-flex; width: 17px; height: 17px; flex-shrink: 0; }
.btn-meta-icon svg { position: absolute; inset: 0; width: 17px; height: 17px; transition: opacity .15s ease; }
.btn-meta-spin {
    position: absolute; inset: 0; border-radius: 50%;
    border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
    opacity: 0; transition: opacity .15s ease;
}
#connectIcon.loading svg { opacity: 0; }
#connectIcon.loading .btn-meta-spin { opacity: 1; animation: connectSpin .7s linear infinite; }
@keyframes connectSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    #connectIcon.loading .btn-meta-spin { animation: none; }
}

/* The footer: Back on the left, everything else on the right. */
.wiz-foot-acts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.wiz-skip { font-size: 13px; font-weight: 600; color: rgba(0,0,0,.58); }
.wiz-skip:hover { color: #111; }
.wiz-skip { border: 0; background: transparent; cursor: pointer; padding: 7px 0; font-family: inherit; }

/* Selectable cards, not a form of checkboxes.
   These were 17px squares in cramped boxes, four across on the channel row,
   which at that size is a list of tick boxes wearing a card's border. The
   control is now the whole tile: the mark is a circle that fills and ticks on
   select, the tile lifts and takes a green ring, and the channel row wraps as
   chips instead of forcing four equal columns into whatever width is left. */
.setup-choices { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 10px; margin-top: 10px; }
.setup-choices-channels { display: flex; flex-wrap: wrap; grid-template-columns: none; }
/* Not white. A white box with a hairline border and rounded corners is
   exactly what the Business name field above these looks like, so drawn that
   way the options read as empty text inputs -- which is how they shipped, and
   why the row looked like six fields nobody had filled in. Tinted ground and
   no visible border until you touch one. */
/* Scoped through .setup-choices on purpose. These tiles are <label>s inside
   a .field, and house.css:472 sets `.field label { display: block }` at a
   higher specificity than a lone .setup-choice -- so the tile never became a
   flex row and the mark fell back to an inline span with no width, which is
   why it rendered as a 2px sliver rather than a circle. That was true of the
   17px square this replaced too; it has been broken since the tiles shipped. */
.setup-choices .setup-choice {
    position: relative;
    margin-bottom: 0;
    min-height: 58px;
    display: flex; align-items: center; gap: 12px;
    padding: 13px 15px;
    border: 1.5px solid transparent; border-radius: 14px;
    background: rgba(20,20,15,.045);
    cursor: pointer;
    font-size: 13.5px; font-weight: 600; line-height: 1.35;
    color: rgba(0,0,0,.74);
    transition: border-color .2s, background .2s, box-shadow .2s, transform .2s;
}
.setup-choice:hover {
    transform: translateY(-2px);
    background: rgba(20,20,15,.06);
    border-color: rgba(11,129,90,.4);
    box-shadow: 0 10px 24px rgba(17,17,17,.07);
}
.setup-choice:hover .setup-choice-mark { border-color: rgba(11,129,90,.55); }
.setup-choice input { position: absolute; opacity: 0; pointer-events: none; }
.setup-choice input:focus-visible ~ .setup-choice-mark { box-shadow: 0 0 0 4px rgba(11,129,90,.22); }
/* A circle, because these are things you are turning on, and because a round
   mark stops reading as the square tick box the tile already replaced. */
.setup-choice-mark {
    width: 22px; height: 22px; flex: 0 0 22px;
    border: 1.5px solid rgba(0,0,0,.28); border-radius: 50%;
    background: #fff; position: relative;
    box-shadow: inset 0 1px 2px rgba(0,0,0,.06);
    transition: background .18s, border-color .18s, box-shadow .18s;
}
/* A real check, centred by the box rather than nudged into place. The
   hand-drawn version -- two borders on a pseudo-element, rotated 45deg and
   offset with left/top -- has no reliable optical centre, which is why it sat
   low and to the right of the circle. A centred SVG has nothing to nudge. */
.setup-choice-mark::after {
    content: ''; position: absolute; inset: 0;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center / 12px 12px no-repeat;
    opacity: 0;
    transform: scale(.4);
    transition: opacity .14s, transform .22s cubic-bezier(.2,1.5,.5,1);
}
.setup-choice input:checked ~ .setup-choice-mark { background: #0B815A; border-color: #0B815A; box-shadow: none; }
.setup-choice input:checked ~ .setup-choice-mark::after { opacity: 1; transform: scale(1); }
.setup-choice:has(input:checked) {
    background: rgba(11,129,90,.08);
    border-color: #0B815A;
    color: #0a4f3b;
}
/* The channel row: chips that size to their label rather than four columns
   squeezed to the width of the longest one. */
.setup-choice.compact {
    min-height: 46px; flex: 0 1 auto;
    padding: 11px 16px 11px 13px; border-radius: 100px;
    font-size: 13px;
}
.setup-choice.compact .setup-choice-mark { width: 19px; height: 19px; flex-basis: 19px; }
.setup-choice.compact .setup-choice-mark::after { background-size: 10px 10px; }
@media (max-width: 620px) { .setup-choices { grid-template-columns: 1fr; } }
.setup-guide { margin: 14px 0; border: 1px solid rgba(0,0,0,.08); border-radius: 13px; background: #faf9f6; overflow: hidden; }
.setup-guide summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.setup-guide summary::-webkit-details-marker { display: none; }.setup-guide summary > span:last-child { display: flex; flex-direction: column; gap: 2px; }
.setup-guide summary b { font-size: 12.5px; }.setup-guide summary small { color: rgba(0,0,0,.52); font-size: 11.5px; }
.guide-play { width: 27px; height: 27px; border-radius: 50%; display: grid; place-items: center; flex: 0 0 27px; padding-left: 2px; background: #111; color: #fff; font-size: 9px; }
.guide-frames { display: grid; grid-template-columns: repeat(3,1fr); gap: 7px; padding: 0 10px 10px; }
.guide-frames > div { min-height: 102px; padding: 11px; border-radius: 10px; background: #fff; border: 1px solid rgba(0,0,0,.06); display: flex; flex-direction: column; gap: 4px; animation: guideFrame .45s both; }
.guide-frames > div:nth-child(2) { animation-delay: .1s; }.guide-frames > div:nth-child(3) { animation-delay: .2s; }
.guide-frames i { width: 20px; height: 20px; display: grid; place-items: center; border-radius: 50%; background: rgba(11,129,90,.1); color: #0B815A; font-size: 10px; font-weight: 750; font-style: normal; margin-bottom: 4px; }
.guide-frames b { font-size: 11.5px; }.guide-frames small { font-size: 10.5px; line-height: 1.45; color: rgba(0,0,0,.55); }
@keyframes guideFrame { from { opacity: 0; transform: translateY(6px); } }
.recommended-path { display: flex; align-items: center; gap: 11px; padding: 13px 14px; margin-bottom: 15px; border: 1px solid rgba(11,129,90,.2); border-radius: 13px; background: rgba(11,129,90,.065); }
.recommended-path > span { font-size: 9.5px; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; color: #0B815A; }
.recommended-path > div { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }.recommended-path b { font-size: 12.5px; }.recommended-path small { font-size: 11px; color: rgba(0,0,0,.55); }
.choice-divider { display: flex; align-items: center; gap: 10px; margin: 5px 0 17px; color: rgba(0,0,0,.42); font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; }.choice-divider::before,.choice-divider::after { content: ''; height: 1px; background: rgba(0,0,0,.08); flex: 1; }
.goal-summary { margin-bottom: 14px; }.goal-summary > span { display: block; margin-bottom: 8px; font-size: 10px; font-weight: 750; text-transform: uppercase; letter-spacing: .07em; color: rgba(0,0,0,.5); }.goal-summary > div { display: flex; flex-wrap: wrap; gap: 6px; }.goal-summary i { font-style: normal; padding: 6px 9px; border-radius: 16px; background: rgba(11,129,90,.08); color: #0a6647; font-size: 11px; font-weight: 650; }

/* Step 2's picker sits under the whole .drop box — see its rule above. */
.drop-input {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
.drop-file { margin-top: 10px; font-size: 12.5px; font-weight: 700; color: #0B815A; }

/* Step 2's already-uploaded files, in the exact shape AI Training lists them
   (.ds-row/.ds-icon there, page-local since only one page used it) -- a
   client who uploaded here and clicked back should see the same file row
   they'd see on the page that owns this data permanently, not a different
   sketch of "you have a file" that happens to live in onboarding. */
.ds-list { margin-bottom: 18px; display: flex; flex-direction: column; gap: 8px; }
.ds-row {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 14px; border: 1px solid rgba(0,0,0,.08); border-radius: 10px;
    background: #fff;
}
.ds-icon {
    width: 34px; height: 34px; border-radius: 8px; flex-shrink: 0;
    background: #f0f0ee; display: flex; align-items: center; justify-content: center;
}

/* Step 5's phone, and only step 5's now -- step 3 shows the connected number
   as a plain .chan card, matching step 4's the way it always should have.
   A real device, not a rounded rectangle standing in for one: a titanium
   edge, a dynamic-island notch, physical buttons on the frame, a home
   indicator, and a tall enough aspect ratio to read as hand-held. */
/* The flat "Test Your AI" panel from ai-training.php, not a phone: the
   iPhone chrome read as a cheap prop rather than the product, and the app
   already has its own sandbox design elsewhere on this exact feature --
   this now matches it directly rather than inventing a second look for the
   same idea. Values (header padding, icon badge, thread background,
   border-radius, shadow) are lifted from that page rather than approximated. */
.sandbox {
    background: #fff; border: 1px solid rgba(0,0,0,.06); border-radius: 20px;
    box-shadow: 0 16px 40px rgba(0,0,0,.12);
    display: flex; flex-direction: column; overflow: hidden;
    max-width: 460px; margin: 0 auto; height: 460px;
}
.sandbox-bar { display: flex; align-items: center; gap: 11px; padding: 14px 18px; background: #111; flex-shrink: 0; }
.sandbox-ico {
    width: 30px; height: 30px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
    background: linear-gradient(135deg, rgba(255,255,255,.22), rgba(255,255,255,.08));
    border: 1px solid rgba(255,255,255,.22);
}
.sandbox-name { font-size: 13px; font-weight: 600; color: #fff; display: block; }
.sandbox-sub { font-size: 10.5px; color: rgba(255,255,255,.55); display: block; margin-top: 1px; }
.sandbox .thread { flex: 1; overflow-y: auto; background: #efece6; padding: 16px; gap: 10px; }
.sandbox-empty { padding: 0; display: flex; flex: 1; }
.sandbox-empty .empty { margin: auto; padding: 26px 24px; }
.sandbox-send {
    display: flex; gap: 9px; padding: 12px 14px;
    background: #fff; border-top: 1px solid rgba(0,0,0,.07);
}
.sandbox-send input {
    flex: 1; min-width: 0; padding: 10px 13px;
    background: #fafaf8; border: 1px solid rgba(0,0,0,.12); border-radius: 10px;
    font-family: inherit; font-size: 13.5px; color: #111; outline: none;
}
.sandbox-send input:focus { border-color: #111; box-shadow: 0 0 0 3px rgba(0,0,0,.06); background: #fff; }
.sandbox-send .btn { padding: 10px 14px; }
.sandbox-send .btn svg { width: 16px; height: 16px; }

/* Openers. A blank box at the step where someone was about to be convinced is
   the most expensive empty field in the product. */
.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.chip {
    padding: 7px 13px; border-radius: 20px;
    border: 1px solid rgba(0,0,0,.12); background: #fff;
    font-family: inherit; font-size: 12.5px; font-weight: 500;
    color: rgba(0,0,0,.7); cursor: pointer;
}
.chip:hover { border-color: #111; color: #111; }

/* The switch that turns the product on, on the last step -- same shape as
   the bot toggle on AI Training (switch, bold status, one short caption)
   rather than its own bespoke control with a paragraph explaining a setting
   that page already explains. */
.wiz-live {
    display: flex; align-items: center; gap: 16px;
    padding: 16px 20px; border-radius: 14px;
    border: 1px solid rgba(11,129,90,.3); background: rgba(11,129,90,.04);
}
.wiz-live-ttl { font-size: 14px; font-weight: 700; color: #111; }
.wiz-live-txt { font-size: 12px; color: rgba(0,0,0,.68); margin-top: 2px; }

.live-test-intro { text-align: center; padding: 14px 12px 22px; }
.live-test-intro h2 { margin: 16px 0 7px; font-size: 19px; letter-spacing: -.02em; }
.live-test-intro p { max-width: 430px; margin: 0 auto; font-size: 13px; line-height: 1.6; color: rgba(0,0,0,.6); }
.live-test-orbit { width: 86px; height: 86px; margin: 0 auto; border-radius: 50%; background: rgba(11,129,90,.07); display: grid; place-items: center; position: relative; }
.live-test-orbit img { border-radius: 10px; position: relative; z-index: 2; }
.live-test-orbit i { position: absolute; inset: 8px; border: 1px solid rgba(11,129,90,.2); border-radius: 50%; animation: testOrbit 2.4s ease-out infinite; }
.live-test-orbit i:nth-child(3) { animation-delay: .8s; }.live-test-orbit i:nth-child(4) { animation-delay: 1.6s; }
@keyframes testOrbit { 0% { transform: scale(.55); opacity: .8; } 100% { transform: scale(1.35); opacity: 0; } }
.live-test { border: 1px solid rgba(11,129,90,.16); border-radius: 17px; overflow: hidden; background: linear-gradient(145deg,rgba(11,129,90,.045),#fff 60%); }
.live-test-head { display: flex; align-items: center; gap: 11px; padding: 15px 17px; border-bottom: 1px solid rgba(0,0,0,.06); }
.live-test-head > div { display: flex; flex-direction: column; gap: 2px; }.live-test-head b { font-size: 13px; }.live-test-head small { font-size: 11.5px; color: rgba(0,0,0,.52); }
.live-pulse { width: 10px; height: 10px; border-radius: 50%; background: #0B815A; box-shadow: 0 0 0 0 rgba(11,129,90,.35); animation: livePulse 1.8s infinite; }
@keyframes livePulse { 70% { box-shadow: 0 0 0 8px rgba(11,129,90,0); } 100% { box-shadow: 0 0 0 0 rgba(11,129,90,0); } }
.live-steps { list-style: none; margin: 0; padding: 8px 17px; }
.live-steps li { display: flex; align-items: flex-start; gap: 12px; padding: 13px 0; color: rgba(0,0,0,.45); }
.live-steps li + li { border-top: 1px solid rgba(0,0,0,.055); }
.live-steps li > span { width: 24px; height: 24px; border-radius: 50%; background: rgba(0,0,0,.07); display: grid; place-items: center; flex: 0 0 24px; font-size: 10px; font-weight: 750; }
.live-steps li > div { display: flex; flex-direction: column; gap: 3px; }.live-steps b { font-size: 13px; color: rgba(0,0,0,.65); }.live-steps small { font-size: 11.8px; line-height: 1.45; }
.live-steps li.active > span { background: #111; color: #fff; }.live-steps li.active b { color: #111; }
.live-steps li.done { color: #15803d; }.live-steps li.done > span { background: #0B815A; color: #fff; font-size: 0; }.live-steps li.done > span::after { content: '✓'; font-size: 12px; }.live-steps li.done b { color: #0a6647; }
.live-result { margin: 0 17px 17px; padding: 13px 14px; border-radius: 11px; font-size: 12.5px; line-height: 1.55; }.live-result.ok { background: rgba(11,129,90,.09); color: #0a6647; }.live-result.bad { background: rgba(185,28,28,.07); color: #991b1b; }

@media (max-width: 560px) {
    .wiz-foot { flex-direction: column; align-items: stretch; }
    .wiz-foot-acts { justify-content: space-between; }
    /* On a phone the canvas around the card is width the content needs more
       than the framing does, so the margin shrinks and the corners with it. */
    .wiz-wrap { padding: 12px; }
    .wiz { border-radius: 20px; }
    .setup-choices, .setup-choices-channels { grid-template-columns: 1fr; }
    .setup-choice.compact { justify-content: flex-start; }
    .guide-frames { grid-template-columns: 1fr; }
    .recommended-path { align-items: flex-start; flex-wrap: wrap; }.recommended-path > span { width: 100%; }.recommended-path .btn { margin-left: auto; }
}

/* Motion is decoration here -- every one of these animations exists to make
   the flow feel continuous, and none of them carries information. Somebody
   who has asked their system not to animate loses nothing by switching them
   all off, and gets to use setup without being made ill by it. */
@media (prefers-reduced-motion: reduce) {
    .wiz-panel { animation: none; }
    /* The dot on the current step pulses forever, so it is the one that most
       needs switching off -- it keeps going long after the page has settled.
       Without animation it is still a filled green dot, which is the whole of
       what it was saying. */
    .step-mark.dot { animation: none; }
    .wiz-card, .wiz-progress i, .step-num, .step, .step-ttl { transition: none; }
    .live-test-orbit i, .live-pulse { animation: none; }
    .guide-frames > div { animation: none; }
}

/* The Meta mark is a solid shape, not a line icon. `.btn svg` above turns
   every button glyph into an outline, which is right for the wizard's own
   check and warning marks and traces this one into a ghost. */
.meta-mark, .btn svg.meta-mark { fill: currentColor; stroke: none; }

/* The channel glyphs are solid shapes, same reasoning as .meta-mark above:
   `.btn svg` traces button icons into outlines, which these are not. */
.wa-mark, .btn svg.wa-mark { fill: currentColor; stroke: none; }

/* ------------------------------------------------- step 5, the try-it panel
   The one screen in setup where the product talks back, so it gets its own
   ground instead of another white card with a green hairline. The band across
   the top is the green -- solid, with the copy on it -- rather than green text
   inside a tinted box, which is what every other panel in the flow already
   does and what made this step read as more of the same. */
/* Step 5 -- the one screen that answers back.
   The first attempt sat the whole thing on a green gradient, which made a
   quiet feature shout and put green somewhere it does not mean "live". Same
   relationship as everywhere else now: the site's warm ground, one dark band
   stating what is about to happen, and the conversation on white inside it.
   Green is left to do its single job -- the dot that says it is listening. */
.trybox {
    margin: 6px -14px 0;
    max-width: 780px;
    border-radius: 20px;
    overflow: hidden;
    background: #eceae4;
    border: 1px solid rgba(0,0,0,.07);
    animation: tryboxIn .42s cubic-bezier(.2,.7,.3,1) both;
}
@keyframes tryboxIn { from { opacity: 0; transform: translateY(12px); } }
@media (prefers-reduced-motion: reduce) { .trybox { animation: none; } }
.trybox-head {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 16px 20px 17px;
    background: #111;
    color: #fff;
}
.trybox-head-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.trybox-head-txt b { font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.trybox-head-txt small { font-size: 11.5px; line-height: 1.5; color: rgba(255,255,255,.62); }
/* Breathing, not blinking. It is the only green on the panel and it means
   the sandbox is listening -- the same thing green means everywhere else. */
.trybox-live {
    width: 8px; height: 8px; flex-shrink: 0; margin-top: 6px;
    border-radius: 50%; background: #0B815A;
    box-shadow: 0 0 0 0 rgba(11,129,90,.55);
    animation: tryPulse 2.2s ease-out infinite;
}
@keyframes tryPulse {
    0%   { box-shadow: 0 0 0 0 rgba(11,129,90,.55); }
    70%  { box-shadow: 0 0 0 8px rgba(11,129,90,0); }
    100% { box-shadow: 0 0 0 0 rgba(11,129,90,0); }
}
@media (prefers-reduced-motion: reduce) { .trybox-live { animation: none; } }
.trybox .sandbox {
    border-radius: 14px;
    margin: 14px 14px 0;
    background: #fff;
    border: 1px solid rgba(0,0,0,.07);
    box-shadow: none;
    overflow: hidden;
}
.trybox .chips { padding: 12px 14px 16px; margin: 0; }
@media (max-width: 620px) {
    .trybox { margin: 6px 0 0; border-radius: 16px; }
    .trybox .sandbox { margin: 12px 10px 0; }
}

/* ------------------------------------------------------- crumb refinement
   Three marks that were three different sizes and weights read as three
   unrelated things. One 24px circle, tabular numerals, and separators quiet
   enough to be punctuation rather than another element competing for a look. */
.wiz-crumbs { gap: 8px; }
.wiz-crumb { gap: 10px; font-size: 13px; }
.wiz-crumb-n {
    width: 24px; height: 24px;
    border-width: 1.5px;
    font-size: 12px;
}
.wiz-crumb.current .wiz-crumb-n { background: #111; border-color: #111; }
.wiz-crumb-sep svg { width: 13px; height: 13px; }
.wiz-crumb-sep { color: rgba(0,0,0,.16); }

/* ------------------------------------------------------- Google sign-in
   White, bordered, mark on the left -- the shape Google's own guidance asks
   for, and deliberately not the dark .btn the form's own submit uses, so the
   provider button and the account you are creating never look like the same
   action. */
.google-btn {
    width: 100%; min-height: 48px;
    display: flex; align-items: center; justify-content: center; gap: 10px;
    background: #fff; color: #24252a;
    border: 1px solid rgba(0,0,0,.16);
    border-radius: 12px;
    font-size: 14px; font-weight: 650;
    box-shadow: 0 1px 2px rgba(0,0,0,.04);
    transition: border-color .16s, background .16s, transform .16s;
}
.google-btn:hover { background: #fafafa; border-color: rgba(0,0,0,.3); transform: translateY(-1px); }
/* The mark keeps its own four colours -- .btn svg's outline rule would trace
   it into a grey scribble, the same way it did the Meta mark. */
.google-mark, .btn svg.google-mark { width: 19px; height: 19px; flex-shrink: 0; fill: initial; stroke: none; }
.or-line {
    display: flex; align-items: center; gap: 12px;
    margin: 20px 0;
    color: rgba(0,0,0,.42); font-size: 11.5px;
}
.or-line::before, .or-line::after { content: ''; flex: 1; height: 1px; background: rgba(0,0,0,.09); }

/* ========================================================================
   Focused account + setup journey
   Claude's approved flow is intentionally narrow: one real question at a
   time, one column on every screen, and one successful channel is enough.
   These rules use the app's existing Inter/green/ink palette; they do not
   import the prototype's serif or terracotta theme. */

.wiz-wrap { background: #f3f1ec; }
.onboarding-col { max-width: 760px !important; }
.onboarding-flow {
    overflow: visible; background: transparent; border-radius: 0; box-shadow: none;
}
.onboarding-flow .wiz-top {
    width: 100%; padding: 2px 4px 24px; border: 0;
}
.onboarding-flow .wiz-top .brand::after { display: none; }
.onboarding-flow .wiz-top-right > .muted { display: none; }
.onboarding-flow .wiz-back { background: rgba(255,255,255,.65); }
.onboarding-flow .wiz-body { display: block; min-height: 0; }
.onboarding-flow .wiz-panel {
    width: 100%; min-width: 0; padding: 40px 44px 44px;
    display: block; border: 1px solid rgba(0,0,0,.075); border-radius: 22px;
    background: #fff; box-shadow: 0 24px 64px rgba(27,24,19,.09);
}
.onboarding-flow .wiz-panel > * { width: 100%; max-width: none; }
.onboarding-flow .wiz-crumbs {
    display: grid; grid-template-columns: repeat(3,minmax(0,1fr));
    align-items: start; gap: 8px; margin: 0 0 34px;
}
.onboarding-flow .wiz-crumb-sep { display: none; }
.onboarding-flow .wiz-crumb {
    min-width: 0; display: flex; flex-direction: column; align-items: stretch; gap: 8px;
    color: rgba(0,0,0,.38); font-size: 10.5px; font-weight: 700;
    letter-spacing: .025em; text-transform: uppercase;
}
.onboarding-flow .wiz-crumb-n {
    width: 100%; height: 4px; min-height: 4px; display: block; overflow: hidden;
    border: 0; border-radius: 999px; background: rgba(0,0,0,.1);
    color: transparent; font-size: 0;
}
.onboarding-flow .wiz-crumb-n svg { display: none; }
.onboarding-flow .wiz-crumb.current { color: #111; }
.onboarding-flow .wiz-crumb.current .wiz-crumb-n { background: #111; }
.onboarding-flow .wiz-crumb.done { color: rgba(11,129,90,.82); }
.onboarding-flow .wiz-crumb.done .wiz-crumb-n { background: #0B815A; }
.onboarding-flow .wiz-crumb-l { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.onboarding-flow .wiz-eyebrow { margin-bottom: 11px; color: #0B815A; }
.onboarding-flow .wiz-title { max-width: 18ch; margin-bottom: 12px; font-size: 32px; line-height: 1.08; }
.onboarding-flow .wiz-lede { max-width: 58ch; margin-bottom: 26px; font-size: 14.5px; }
.onboarding-flow .wiz-foot { margin-top: 28px; padding-top: 22px; border-top: 1px solid rgba(0,0,0,.07); }

.setup-identity {
    display: grid; grid-template-columns: 1.05fr .95fr; gap: 14px;
    margin-bottom: 8px; padding: 16px 16px 2px;
    border-radius: 15px; background: #f7f6f3;
}
.setup-question { margin-top: 24px; }
.setup-question > label { font-size: 14px; }
.onboarding-flow .setup-choices { gap: 9px; }
.onboarding-flow .setup-choices .setup-choice {
    min-height: 54px; padding: 12px 14px; border-radius: 13px;
    background: #f7f6f3; border-color: transparent; box-shadow: none;
}
.onboarding-flow .setup-choice:hover { transform: none; box-shadow: none; background: #f1f0ec; }
.onboarding-flow .setup-choice:has(input:checked) { background: rgba(11,129,90,.075); border-color: rgba(11,129,90,.5); }
.setup-more { margin-top: 18px; border-top: 1px solid rgba(0,0,0,.07); }
.setup-more summary {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 16px 2px; list-style: none; cursor: pointer;
    color: rgba(0,0,0,.63); font-size: 12.5px; font-weight: 650;
}
.setup-more summary::-webkit-details-marker { display: none; }
.setup-more summary span { padding: 4px 8px; border-radius: 999px; background: rgba(0,0,0,.055); font-size: 10px; text-transform: uppercase; letter-spacing: .04em; }
.setup-more[open] { padding-bottom: 4px; }

.setup-trust {
    display: flex; align-items: flex-start; gap: 12px; margin-bottom: 18px;
    padding: 14px 15px; border-radius: 14px;
    border: 1px solid rgba(11,129,90,.16); background: rgba(11,129,90,.055);
}
.setup-trust span { flex-shrink: 0; padding: 5px 8px; border-radius: 999px; background: #0B815A; color: #fff; font-size: 9.5px; font-weight: 750; letter-spacing: .05em; text-transform: uppercase; }
.setup-trust p { margin: 0; color: rgba(0,0,0,.65); font-size: 12.5px; line-height: 1.55; }
.setup-facts > .field, .setup-facts > .field-row {
    padding: 15px 15px 1px; border: 1px solid rgba(0,0,0,.075); border-radius: 14px; background: #faf9f7;
}
.setup-facts > .field-row { padding-bottom: 1px; margin-bottom: 14px; }
.setup-facts > .field { margin-bottom: 14px; }

.setup-channel-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 14px; }
.setup-channel-grid.single { grid-template-columns: 1fr; }
.setup-channel-card {
    display: flex; flex-direction: column; min-width: 0; padding: 20px;
    border: 1px solid rgba(0,0,0,.085); border-radius: 17px; background: #faf9f7;
}
.setup-channel-head { display: flex; align-items: flex-start; gap: 12px; }
.setup-channel-head .chan-logo { width: 38px; height: 38px; flex: 0 0 38px; border-radius: 11px; }
.setup-channel-head .chan-logo.meta { background: #111; color: #fff; }
.setup-channel-head h2 { margin: 1px 0 4px; font-size: 16px; line-height: 1.2; letter-spacing: -.015em; }
.setup-channel-head p { margin: 0; color: rgba(0,0,0,.56); font-size: 12px; line-height: 1.45; }
.setup-channel-card ul { flex: 1; margin: 17px 0 20px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.setup-channel-card li { position: relative; padding-left: 18px; color: rgba(0,0,0,.62); font-size: 12px; line-height: 1.45; }
.setup-channel-card li::before { content: '✓'; position: absolute; left: 0; color: #0B815A; font-weight: 800; }
.setup-channel-card .btn { justify-content: center; min-height: 48px; }
.setup-channel-card .wa-mark { width: 18px; height: 18px; }
.setup-connection-note { display: flex; flex-direction: column; gap: 3px; margin: 16px 0 4px; padding: 13px 15px; border-radius: 13px; background: rgba(11,129,90,.055); }
.setup-connection-note b { font-size: 12.5px; }.setup-connection-note span { color: rgba(0,0,0,.57); font-size: 11.5px; line-height: 1.5; }

/* ========================================================================
   Signup Direction 1B
   Palette note: these tokens are whacl.com's, copied value for value from the
   marketing site's :root (--site-canvas/--site-paper/--site-ink/--site-green).
   Somebody arriving from the homepage should not be able to tell they changed
   sites, so a colour here that the homepage does not use is a bug.
   The public account page is the promise, not a tiny form stranded in a
   generic card. Its left panel names what the product does; the right panel
   keeps the one job — create an account — calm and short. This is intentionally
   scoped to .signup-v1b so staff workspace creation and sales requests retain
   their existing, truthful flows. */
.signup-v1b {
    --signup-canvas: #edf0f5;
    --signup-surface: #edf0f5;
    --signup-pitch: #fbfcfe;
    --signup-paper: #fff;
    --signup-control: #f4f6fa;
    --signup-line: #e0e4eb;
    --signup-ink: #202124;
    --signup-muted: #5f6672;
    --signup-green: #147451;
    --signup-green-dark: #0f5c41;
    --signup-green-accent: #0b815a;
    --signup-green-soft: #e7f1ec;
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(390px, 43.5%) 1fr;
    background: var(--signup-canvas);
    color: var(--signup-ink);
}
.signup-v1b-pitch {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 52px clamp(42px, 5.4vw, 78px) 44px;
    /* Deep green, restored. A light panel beside the light form column left
       the whole page one flat white sheet with nothing anchoring it; the
       green is what makes this read as a front door. The form column stays
       on the homepage's canvas, so the two sites still meet in the middle. */
    background: #0b3024;
    color: #f8f7f1;
}
.signup-v1b-brand {
    display: inline-flex; align-items: center; gap: 10px;
    width: fit-content;
    color: #f8f7f1; font-size: 24px; font-weight: 800; letter-spacing: -.045em;
    text-decoration: none;
    transition: opacity .16s;
}
.signup-v1b-brand:hover { opacity: .8; }
/* No chip behind it. The mark's own bubble is near-black on transparent, which
   is a shade the panel does not have -- it reads as its own object against the
   green, and the cream W inside carries the contrast. */
.signup-v1b-brand img { width: 36px; height: 36px; }
.signup-v1b-story { margin: auto 0; max-width: 510px; }
/* Citrion at the homepage hero's own size and tracking. The accent line uses
   the panel's own mint rather than the hero's #0b815a, which is a dark-on-dark
   at 2.1:1 against this green. */
.signup-v1b-story h1 {
    margin: 0;
    color: #f8f7f1;
    font-family: Citrion, Inter, serif;
    font-size: clamp(40px, 4.4vw, 56px);
    font-weight: 400;
    letter-spacing: -.03em;
    line-height: 1.06;
}
.signup-v1b-story h1 em { color: #61d8a0; font-style: normal; }
.signup-v1b-story p { max-width: 420px; margin: 22px 0 0; color: rgba(248,247,241,.8); font-size: 17px; line-height: 1.65; }
.signup-v1b-signals { display: flex; flex-direction: column; gap: 10px; padding-top: 26px; border-top: 1px solid rgba(248,247,241,.16); }
.signup-v1b-label { margin-top: 13px; color: #78d8ab; font-size: 10px; font-weight: 750; letter-spacing: .2em; text-transform: uppercase; }
.signup-v1b-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; }
/* Marks, not names. Sized so the four channel glyphs and the three model
   glyphs read as one row of the same object -- a chip that changes width per
   brand would make WhatsApp look more important than Gemini. */
.signup-v1b-pill {
    display: grid; place-items: center;
    color: #f8f7f1;
    opacity: .88;
    transition: opacity .16s;
}
.signup-v1b-pill:hover { opacity: 1; }
.signup-v1b-pill svg { width: 26px; height: 26px; }
.signup-v1b-logo { width: 26px; height: 26px; }
/* OpenAI ships this mark as solid black on transparent, which is nothing at
   all against dark green. White is their own dark-background lockup, and a
   solid-black source is the one case where a filter reproduces it exactly
   rather than approximating it. Claude's orange and Gemini's gradient are
   already legible here and are left alone. */
.signup-v1b-pill[data-provider="openai"] .signup-v1b-logo { filter: brightness(0) invert(1); }

.signup-v1b-main { position: relative; display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 92px 48px 45px; background: var(--signup-surface); }
.signup-v1b-form {
    width: min(100%, 520px); margin: auto;
}
.signup-v1b-main.is-personalizing { justify-content: center; padding: 42px clamp(32px,4vw,58px); }
.signup-v1b-form.signup-personalization {
    width: min(100%, 680px); padding: 29px 30px 24px;
    border: 1px solid rgba(16,32,28,.1); border-radius: 22px;
    background: rgba(255,255,255,.88); box-shadow: 0 20px 50px rgba(16,32,28,.08);
}
.signup-personalization > h1 { font-size: 32px; }
.signup-personalization > .signup-v1b-sub { margin-bottom: 18px; }
.signup-v1b-form > h1 { margin: 0 0 8px; color: var(--signup-ink); font-size: 36px; font-weight: 780; letter-spacing: -.05em; line-height: 1.08; }
.signup-v1b-sub { margin: 0 0 30px; color: var(--signup-muted); font-size: 15px; line-height: 1.5; }
.signup-v1b form { display: flex; flex-direction: column; gap: 20px; }
.signup-v1b .field { margin: 0; }
.signup-v1b .field label { display: block; margin-bottom: 7px; color: var(--signup-ink); font-size: 12px; font-weight: 650; }
.signup-v1b .field input[type=text],
.signup-v1b .field input[type=email],
.signup-v1b .field input[type=password],
.signup-v1b .field select { width: 100%; min-height: 56px; padding: 12px 14px; border: 1px solid var(--signup-line); border-radius: 11px; background: var(--signup-paper); color: var(--signup-ink); font: inherit; font-size: 14px; }
.signup-v1b .field input:focus, .signup-v1b .field select:focus { border-color: var(--signup-green); outline: 0; box-shadow: 0 0 0 3px rgba(11,129,90,.16); background: #fff; }
.signup-input-shell {
    display: flex; min-height: 56px; align-items: center; gap: 11px; padding: 0 14px;
    border: 1px solid var(--signup-line); border-radius: 11px; background: var(--signup-paper);
    transition: border-color .12s, box-shadow .12s, background .12s;
}
.signup-input-shell:hover { border-color: #c3c0b6; }
.signup-input-shell:focus-within { border-color: var(--signup-green); box-shadow: 0 0 0 3px rgba(11,129,90,.16); background: #fff; }
.signup-input-shell > svg { width: 19px; height: 19px; flex: 0 0 19px; fill: none; stroke: rgba(16,32,28,.48); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.signup-v1b .field .signup-input-shell > input[type=text] { min-height: 54px; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
.signup-v1b .field .signup-input-shell > input[type=text]:focus { border: 0; background: transparent; box-shadow: none; }
.signup-v1b-workspace { margin: 8px 0 0; color: rgba(16,32,28,.58); font-size: 11.5px; line-height: 1.45; }
.signup-v1b-workspace b { color: #0b7852; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 750; }
.signup-v1b .field-msg { margin-top: 7px; font-size: 11.5px; font-weight: 520; }
.signup-v1b .signup-advanced { display: none; }
.signup-v1b .btn.lg { min-height: 52px; padding: 13px 22px; border: 1px solid var(--signup-green); border-radius: 11px; background: var(--signup-green); color: #fff; box-shadow: 0 3px 8px rgba(20,116,81,.18); font-size: 14px; font-weight: 680; }
.signup-v1b .btn.lg:hover { border-color: var(--signup-green-dark); background: var(--signup-green-dark); transform: none; filter: none; }
.signup-v1b-reassure { margin: 0; color: rgba(16,32,28,.63); font-size: 12.5px; line-height: 1.55; }
.signup-v1b .auth-note { margin: 0; color: rgba(16,32,28,.58); font-size: 11.5px; line-height: 1.55; text-align: left; }
.signup-v1b .auth-note a, .signup-v1b-login a { color: #10201c; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.signup-v1b-login { position: absolute; top: 49px; right: 52px; margin: 0; color: rgba(16,32,28,.67); font-size: 13px; }

/* Login's own two additions. Google's button is required by their branding
   terms to carry the four-colour mark on a plain surface, so it is a white
   button rather than the green one below it -- which is also the honest
   reading: the green button is this product's action, this one hands off. */
.signup-v1b-google {
    display: flex; align-items: center; justify-content: center; gap: 11px;
    min-height: 56px; margin-bottom: 22px;
    border: 1.5px solid #dedbd3; border-radius: 10px;
    background: #fff; color: #13231f;
    font-size: 14.5px; font-weight: 720; text-decoration: none;
}
.signup-v1b-google:hover { border-color: #c9c5ba; background: #fbfaf8; }
.signup-v1b-google:focus-visible { outline: 3px solid #147451; outline-offset: 3px; }
.signup-v1b-google:active { transform: translateY(1px); }
.signup-v1b-field-note { margin: 8px 0 0; color: rgba(16,32,28,.67); font-size: 12.5px; line-height: 1.5; }
.signup-v1b-field-note a { color: #10201c; font-weight: 700; text-underline-offset: 2px; }
.signup-v1b-or {
    display: flex; align-items: center; gap: 14px;
    margin-bottom: 22px;
    color: rgba(16,32,28,.45); font-size: 11.5px; font-weight: 620;
    text-transform: uppercase; letter-spacing: .12em;
}
.signup-v1b-or::before, .signup-v1b-or::after { flex: 1; height: 1px; background: #e6e3db; content: ""; }
.identity-stack { display: grid; gap: 10px; }
.identity-provider {
    min-height: 54px; padding: 0 17px; display: flex; align-items: center; gap: 13px;
    border: 1px solid #dedbd3; border-radius: 10px; background: #fbfaf8;
    color: #13231f; font-size: 14px; font-weight: 700; text-decoration: none;
    transition: transform .16s ease, background .16s ease, border-color .16s ease;
}
.identity-provider > svg, .identity-provider .identity-google { width: 22px; height: 22px; flex: 0 0 22px; }
.identity-provider .meta-mark { fill: currentColor; stroke: none; }
.identity-provider:hover { background: #f3f1eb; border-color: #c9c5ba; }
.identity-provider:focus-visible { outline: 3px solid #147451; outline-offset: 3px; }
.identity-provider:active { transform: scale(.985); }
.identity-provider.is-unavailable { color: rgba(16,32,28,.52); cursor: not-allowed; }
.identity-provider small { margin-left: 7px; color: rgba(16,32,28,.52); font-size: 11px; font-weight: 600; }
.identity-letter { width: 22px; text-align: center; font-size: 20px; font-weight: 800; }
.identity-verified { display: flex; align-items: center; gap: 11px; padding: 13px 14px; border-radius: 10px; background: #edf6f1; color: #10201c; }
.identity-verified > span { width: 25px; height: 25px; display: grid; place-items: center; border-radius: 50%; background: #147451; color: #fff; font-weight: 800; }
.identity-verified strong, .identity-verified small { display: block; }
.identity-verified small { margin-top: 2px; color: rgba(16,32,28,.65); font-size: 11.5px; }
.signup-personalization form { gap: 19px; margin-top: 23px; }
.signup-personalization-body { display: grid; grid-template-columns: 1fr; align-items: start; gap: 22px; }
.signup-business-fields { display: grid; gap: 16px; }
.signup-purpose-field { min-width: 0; margin: 0; padding: 0; border: 0; }
.signup-purpose-field legend { margin: 0; color: var(--signup-ink); font-size: 12px; font-weight: 650; }
.signup-purpose-grid { display: grid; grid-template-columns: 1fr; gap: 8px; margin-top: 9px; }
.signup-purpose { position: relative; min-width: 0; cursor: pointer; }
.signup-purpose input { position: absolute; opacity: 0; pointer-events: none; }
.signup-purpose > span { display: flex; min-height: 72px; align-items: center; justify-content: flex-start; gap: 10px; padding: 8px 12px; border: 1px solid var(--signup-line); border-radius: 13px; background: var(--signup-paper); box-shadow: 0 2px 8px rgba(0,0,0,.025); text-align: left; transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, transform .12s ease; }
.signup-purpose img { width: 52px; height: 52px; flex: 0 0 52px; object-fit: contain; }
.signup-purpose b { color: var(--signup-ink); font-size: 13.5px; font-weight: 680; line-height: 1.2; }
.signup-purpose:hover > span { border-color: #c9c7be; background: var(--signup-surface); transform: translateY(-1px); }
.signup-purpose input:checked + span { border-color: rgba(11,129,90,.5); background: var(--signup-green-soft); box-shadow: inset 0 0 0 1px rgba(11,129,90,.14); }
.signup-purpose input:focus-visible + span { outline: 2px solid var(--signup-green); outline-offset: 2px; }
.signup-purpose:active > span { background: #ecebe6; }
.signup-details-grid { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 16px; }
.signup-v1b .signup-cs .cs-trigger {
    min-height: 56px; padding: 0 14px; border-color: var(--signup-line);
    border-radius: 11px; background: var(--signup-paper); color: var(--signup-ink);
    font-size: 14px; font-weight: 500;
}
.signup-v1b .signup-cs .cs-trigger:hover { border-color: #c3c0b6; background: var(--signup-paper); }
.signup-v1b .signup-cs.open .cs-trigger { border-color: var(--signup-green); box-shadow: 0 0 0 3px rgba(11,129,90,.16); }
.signup-v1b .signup-cs .cs-trigger svg { width: 14px; height: 14px; stroke: var(--signup-muted); }
.signup-v1b .signup-cs .cs-inline-control { display:flex; min-height:56px; align-items:center; border:1px solid var(--signup-line); border-radius:11px; background:var(--signup-paper); transition:border-color .12s,box-shadow .12s,background .12s; }
.signup-v1b .signup-cs .cs-inline-control:hover { border-color:#c3c0b6; }
.signup-v1b .signup-cs.open .cs-inline-control,.signup-v1b .signup-cs .cs-inline-control:focus-within { border-color:var(--signup-green); background:#fff; box-shadow:0 0 0 3px rgba(11,129,90,.16); }
.signup-v1b .field .signup-cs .cs-inline-input[type=search] { min-width:0; min-height:54px; flex:1; appearance:none; padding:0 4px 0 14px; border:0!important; border-radius:11px; outline:0; background:transparent!important; box-shadow:none!important; color:var(--signup-ink); font:inherit; font-size:14px; }
.signup-v1b .signup-cs .cs-inline-toggle { display:grid; width:48px; min-height:54px; flex:0 0 48px; place-items:center; padding:0; border:0; background:transparent; color:var(--signup-muted); cursor:pointer; }
.signup-v1b .signup-cs .cs-inline-toggle svg { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:2; transition:transform .12s ease; }
.signup-v1b .signup-cs.open .cs-inline-toggle svg { transform:rotate(180deg); }
.signup-v1b .signup-cs .cs-inline-input[type=search]::-webkit-search-cancel-button { display:none; }
.signup-v1b .signup-cs .cs-panel { border-color: var(--signup-line); border-radius: 12px; background: var(--signup-paper); box-shadow: 0 12px 28px rgba(0,0,0,.1); }
.signup-v1b .field .signup-cs .cs-search { display: flex; min-height: 40px; margin: 0 0 6px; padding: 0 10px; border: 1px solid var(--signup-line); border-radius: 9px; background: var(--signup-control); }
.signup-v1b .field .signup-cs .cs-search-input[type=search] { width: 100%; min-height: 38px; padding: 0; border: 0; border-radius: 0; outline: 0; background: transparent; box-shadow: none; color: var(--signup-ink); font-size: 12.5px; }
.signup-v1b .field .signup-cs .cs-search:focus-within { border-color: var(--signup-green); background: #fff; box-shadow: 0 0 0 2px rgba(11,129,90,.14); }
.signup-v1b .signup-cs .cs-options { max-height: 166px; }
.signup-v1b .signup-cs .cs-option { padding: 9px 10px; border-radius: 8px; color: var(--signup-muted); font-size: 12.5px; }
.signup-v1b .signup-cs .cs-option:hover { background: var(--signup-control); color: var(--signup-ink); }
.signup-v1b .signup-cs .cs-option.sel { background: var(--signup-green-soft); color: var(--signup-green-dark); }
.signup-field-help { margin: 6px 0 0; color: rgba(16,32,28,.62); font-size: 11.5px; line-height: 1.45; }
.signup-v1b .field label .info-tip { margin-left: 4px; transform: translateY(-1px); }
.signup-identity-line { display: flex; width: fit-content; max-width: 100%; min-width: 0; align-items: center; gap: 8px; margin: 0; padding: 7px 11px 7px 8px; border-radius: 999px; background: var(--signup-green-soft); color: #10201c; font-size: 12px; }
.signup-identity-line > span { width: 20px; height: 20px; flex: 0 0 20px; display: grid; place-items: center; border-radius: 50%; background: #147451; color: #fff; font-size: 11px; font-weight: 800; }
.signup-identity-line strong { min-width: 0; overflow: hidden; font-weight: 680; text-overflow: ellipsis; white-space: nowrap; }
.signup-identity-line small { margin-left: 2px; color: rgba(16,32,28,.62); font-size: 11px; white-space: nowrap; }
.signup-personalization .btn.lg { min-height: 56px; margin-top: 1px; font-size: 14.5px; }
.signup-form-footer { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-top: -8px; color: rgba(16,32,28,.58); font-size: 11px; }
.signup-form-footer a { flex: 0 0 auto; color: #10201c; font-weight: 680; text-underline-offset: 2px; }
.identity-mail-sent { margin: 4px 0 20px; padding: 18px; border-radius: 12px; background: #edf6f1; color: #294239; }
.identity-mail-sent svg { width: 27px; height: 27px; fill: none; stroke: #147451; stroke-width: 1.8; }
.identity-mail-sent p { margin: 9px 0 0; font-size: 14px; line-height: 1.55; }
.password-fallback { margin-top: 18px; border-top: 1px solid #e6e3db; }
.password-fallback summary { padding: 15px 0; cursor: pointer; color: rgba(16,32,28,.7); font-size: 12.5px; font-weight: 650; }
.password-fallback form { margin-top: 2px; }

/* The Meta window lives outside our page. This is the honest in-between state:
   it takes over only while a real sign-in is opening, reports a recoverable
   blocked popup, and vanishes again if the person cancels. */
.connect-wait {
    position: fixed; z-index: 10000; inset: 0;
    display: flex; flex-direction: column;
    min-height: 100svh; padding: 44px clamp(28px, 5vw, 74px) 38px;
    background: #0b3024; color: #f8f7f1;
}
.connect-wait[hidden] { display: none; }
.connect-wait-top { display: flex; align-items: center; justify-content: space-between; }
.connect-wait-brand { font-size: 25px; font-weight: 800; letter-spacing: -.055em; }
.connect-wait-cancel { border: 0; border-bottom: 1px solid rgba(116,216,171,.36); padding: 2px 0; background: transparent; color: #8ed9b4; font: inherit; font-size: 11px; font-weight: 780; letter-spacing: .16em; text-transform: uppercase; cursor: pointer; }
.connect-wait-cancel:hover { color: #fff; border-color: #fff; }
.connect-wait-center { display: flex; flex: 1; flex-direction: column; align-items: center; justify-content: center; padding: 28px 18px; text-align: center; }
.connect-wait-link { display: flex; align-items: center; gap: 18px; margin-bottom: 54px; }
.connect-wait-link span { padding: 10px 17px; border: 1px solid rgba(116,216,171,.38); border-radius: 999px; color: #75d8ab; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; font-weight: 700; }
.connect-wait-link span:last-child { color: rgba(248,247,241,.9); border-color: rgba(248,247,241,.2); }
.connect-wait-link i { position: relative; width: clamp(108px, 12vw, 180px); height: 1px; background: rgba(248,247,241,.17); }
.connect-wait-link i::after { content: ''; position: absolute; top: 50%; left: 50%; width: 9px; height: 9px; border-radius: 50%; background: #61d8a0; transform: translate(-50%, -50%); box-shadow: 0 0 0 4px rgba(97,216,160,.08); }
.connect-wait-symbol { width: 42px; height: 42px; margin-bottom: 30px; display: grid; place-items: center; }
.connect-wait-symbol.is-opening { border: 4px solid rgba(248,247,241,.2); border-right-color: #61d8a0; border-radius: 50%; animation: connectWaitSpin .75s linear infinite; }
.connect-wait-symbol.is-opening span { display: none; }
.connect-wait-symbol.is-blocked { border: 2px solid #e2a43d; border-radius: 50%; color: #e2a43d; font-size: 27px; font-weight: 800; }
.connect-wait-symbol.is-blocked::before { content: '!'; }
.connect-wait.is-success .connect-wait-symbol { width: 57px; height: 57px; margin-bottom: 28px; border: 0; border-radius: 50%; background: #24b57a; color: #062217; font-size: 31px; font-weight: 900; animation: connectWaitPop .3s cubic-bezier(.2,1.45,.4,1) both; }
.connect-wait.is-success .connect-wait-symbol::before { content: '✓'; }
.connect-wait.is-success .connect-wait-symbol span { display: none; }
.connect-wait h1 { max-width: 700px; margin: 0; color: #f8f7f1; font-size: clamp(30px, 3.1vw, 44px); font-weight: 780; letter-spacing: -.055em; line-height: 1.06; }
.connect-wait-center > p { max-width: 560px; margin: 17px 0 0; color: rgba(229,243,235,.72); font-size: clamp(15px, 1.35vw, 18px); line-height: 1.55; }
.connect-wait-retry { margin-top: 34px; min-height: 58px; border: 0; border-radius: 10px; padding: 14px 28px; background: #24b57a; color: #062217; font: inherit; font-size: 15px; font-weight: 800; cursor: pointer; }
.connect-wait-retry:hover { background: #61d8a0; }
.connect-wait-note { width: min(100%, 650px); align-self: center; margin: 0; color: rgba(182,219,199,.68); font-size: 13px; line-height: 1.55; text-align: center; }
@keyframes connectWaitSpin { to { transform: rotate(360deg); } }
@keyframes connectWaitPop { from { opacity: 0; transform: scale(.6); } }

/* The connection screen itself carries the handoff design. The permission
   facts remain on this page; only their old settings-card presentation goes. */
.connect-scene {
    min-height: 100svh; display: flex; flex-direction: column;
    padding: 44px clamp(28px, 5vw, 74px) 38px;
    background: #0b3024; color: #f8f7f1;
}
.connect-scene-top { display: flex; align-items: center; justify-content: space-between; }
.connect-scene-brand { color: #f8f7f1; font-size: 25px; font-weight: 800; letter-spacing: -.055em; }
.connect-scene-cancel { border-bottom: 1px solid rgba(116,216,171,.36); color: #8ed9b4; font-size: 11px; font-weight: 780; letter-spacing: .16em; text-decoration: none; text-transform: uppercase; }
.connect-scene-cancel:hover { border-color: #fff; color: #fff; }
.connect-scene-main { width: min(100%, 1040px); flex: 1; margin: 0 auto; padding: clamp(50px, 8vh, 104px) 0 45px; }
.connect-scene-link { display: flex; align-items: center; justify-content: center; gap: 18px; margin-bottom: 38px; }
.connect-scene-link span { padding: 10px 17px; border: 1px solid rgba(116,216,171,.38); border-radius: 999px; color: #75d8ab; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; font-weight: 700; }
.connect-scene-link span:last-child { border-color: rgba(248,247,241,.2); color: rgba(248,247,241,.9); }
.connect-scene-link i { position: relative; width: clamp(90px, 12vw, 170px); height: 1px; background: rgba(248,247,241,.17); }
.connect-scene-link i::after { content: ''; position: absolute; top: 50%; left: 50%; width: 9px; height: 9px; border-radius: 50%; background: #61d8a0; transform: translate(-50%, -50%); }
.connect-content { width: min(100%, 760px); margin: 0 auto; }
.connect-title { margin: 0; color: #f8f7f1; font-size: clamp(32px, 3.4vw, 46px); font-weight: 800; letter-spacing: -.052em; line-height: 1.04; text-align: center; }
.connect-lede { max-width: 650px; margin: 13px auto 34px; color: rgba(229,243,235,.73); font-size: 15px; line-height: 1.6; text-align: center; }
.connect-consent { padding: 25px 27px; border: 1px solid rgba(255,255,255,.13); border-radius: 18px; background: rgba(255,255,255,.055); }
.connect-consent-title { margin: 0 0 16px; color: #f8f7f1; font-size: 16px; font-weight: 800; letter-spacing: -.015em; }
.connect-facts { display: grid; gap: 13px; margin: 0; padding: 0; list-style: none; color: rgba(239,247,242,.74); font-size: 14px; line-height: 1.55; }
.connect-facts li { position: relative; padding-left: 24px; color: rgba(239,247,242,.74); list-style: none; }
.connect-facts li::before { content: '✓'; position: absolute; top: 0; left: 0; color: #61d8a0; font-weight: 900; }
.connect-facts b { color: #f8f7f1; }
.connect-primary { width: 100%; min-height: 58px; display: flex; align-items: center; justify-content: flex-start; gap: 11px; margin-top: 18px; border: 0; border-radius: 10px; padding: 14px 18px; color: #fff; font: inherit; font-size: 15px; font-weight: 800; text-decoration: none; cursor: pointer; }
.connect-primary-wa { background: #20bf71; box-shadow: 0 16px 34px rgba(32,191,113,.16); }
.connect-primary-wa:hover { background: #35d287; }
.connect-primary-meta { background: #111; box-shadow: 0 16px 34px rgba(0,0,0,.24); }
.connect-primary-meta:hover { background: #262626; }
.connect-explainer, .connect-status { margin: 11px 0 0; color: rgba(206,231,217,.68); font-size: 12.5px; line-height: 1.55; }
.connect-status:empty { display: none; }

/* The Page picker, on the same dark ground as the screen that led to it. The
   heading sits left here rather than centred: this screen is a form with a
   choice in it, and a centred question over a left-aligned list reads as two
   layouts stacked. */
.connect-pick { display: flex; flex-direction: column; }
.connect-pick .connect-title { text-align: left; font-size: clamp(28px, 2.8vw, 40px); }
.connect-pick .connect-lede { max-width: 620px; margin: 13px 0 28px; text-align: left; }
.connect-pick-list { display: flex; flex-direction: column; gap: 10px; margin: 0 0 18px; }
.connect-pick-row {
    display: flex; align-items: center; gap: 15px;
    border: 1px solid rgba(255,255,255,.16); border-radius: 14px;
    padding: 17px 19px; background: rgba(255,255,255,.04); cursor: pointer;
}
.connect-pick-row:hover { border-color: rgba(97,216,160,.45); background: rgba(255,255,255,.06); }
.connect-pick-row input { width: 18px; height: 18px; accent-color: #61d8a0; cursor: pointer; }
.connect-pick-row:has(input:checked) { border-color: #61d8a0; background: rgba(97,216,160,.1); }
.connect-pick-avatar { width: 44px; height: 44px; flex-shrink: 0; border-radius: 12px; object-fit: cover; background: rgba(255,255,255,.08); }
.connect-pick-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* The Instagram account that comes with this Page, set in as a consequence of
   the row rather than beside it as a second choice -- because it is not one. */
.connect-pick-ig {
    display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
    margin-top: 8px; padding-top: 8px;
    border-top: 1px solid rgba(248,247,241,.12);
    color: rgba(206,231,217,.8); font-size: 13px;
}
.connect-pick-ig b { color: #f8f7f1; font-weight: 700; }
.connect-pick-ig-avatar { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; background: rgba(255,255,255,.1); }
.connect-pick-ig-id { color: rgba(206,231,217,.55); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.connect-pick-name { color: #f8f7f1; font-size: 16px; font-weight: 700; letter-spacing: -.015em; }
.connect-pick-id { color: rgba(206,231,217,.62); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
/* The Business a group of ad accounts belongs to, on the dark ground. Same
   answer meta.php's picker gives, in this screen's own palette. */
.connect-pick-group {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    margin: 16px 2px 4px;
    color: #78d8ab; font-size: 11px; font-weight: 750; letter-spacing: .14em; text-transform: uppercase;
}
.connect-pick-list > .connect-pick-group:first-child { margin-top: 0; }
.connect-pick-group-n { color: rgba(206,231,217,.55); font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none; }
/* An account Meta has disabled or closed. Still choosable -- it is theirs, and
   refusing it would be this screen deciding something Meta has not -- but it
   will read no numbers, and the row says so before it is picked. */
.connect-pick-row.is-off { opacity: .62; }
.connect-pick-off {
    margin-left: 8px; padding: 2px 7px; border-radius: 999px;
    background: rgba(224,138,30,.18); color: #f0b860;
    font-size: 10.5px; font-weight: 700; letter-spacing: .02em; text-transform: none;
}
.connect-pick-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.connect-pick-skip {
    border: 0; border-radius: 10px; padding: 14px 18px;
    background: none; color: rgba(206,231,217,.72);
    font: inherit; font-size: 14px; font-weight: 650; cursor: pointer;
}
.connect-pick-skip:hover { color: #f8f7f1; }
.connect-pick-go {
    align-self: flex-start; min-height: 52px; margin-top: 22px;
    border: 0; border-radius: 10px; padding: 14px 26px;
    background: #111; color: #fff; font: inherit; font-size: 15px; font-weight: 800; cursor: pointer;
}
.connect-pick-go:hover { background: #262626; }
.connect-error {
    width: min(100%, 760px); margin: 0 auto 20px; padding: 16px 19px;
    border: 1px solid rgba(255,138,116,.34); border-left-width: 3px; border-radius: 12px;
    background: rgba(255,138,116,.1); color: rgba(255,220,211,.86); font-size: 14px; line-height: 1.55;
}
.connect-error b { display: block; margin-bottom: 3px; color: #ffdcd3; }
.connect-scene .card { border-color: rgba(255,255,255,.13); background: rgba(255,255,255,.055); box-shadow: none; color: #f8f7f1; }
.connect-scene .card p { color: rgba(239,247,242,.72) !important; }
.connect-scene .pick-note { border-color: rgba(255,255,255,.13); background: rgba(255,255,255,.055); color: #f8f7f1; }
.connect-scene .pick-note-ttl, .connect-scene .pick-note-list b { color: #f8f7f1; }
.connect-scene .pick-note-list { color: rgba(239,247,242,.72); }
.connect-scene-note { width: min(100%, 650px); align-self: center; margin: 0; color: rgba(182,219,199,.68); font-size: 13px; line-height: 1.55; text-align: center; }
.connect-scene-success .connect-scene-main { display: flex; flex-direction: column; align-items: center; justify-content: center; padding-bottom: 90px; text-align: center; }
.connect-scene-tick { width: 57px; height: 57px; display: grid; place-items: center; margin: 0 0 28px; border-radius: 50%; background: #24b57a; color: #062217; font-size: 31px; font-weight: 900; animation: connectWaitPop .3s cubic-bezier(.2,1.45,.4,1) both; }
.connect-scene-success h1 { margin: 0; color: #f8f7f1; font-size: clamp(30px, 3.1vw, 44px); letter-spacing: -.055em; }
.connect-scene-success .connect-scene-main > p { margin: 17px 0 0; color: rgba(229,243,235,.72); font-size: 18px; }
.connect-handoff { position: fixed; z-index: 1000; inset: 0; min-height: 100svh; display: flex; flex-direction: column; padding: 44px clamp(28px, 5vw, 74px) 38px; background: #0b3024; color: #f8f7f1; }
.connect-handoff[hidden] { display: none; }
.connect-handoff .connect-scene-cancel { border: 0; border-bottom: 1px solid rgba(116,216,171,.36); padding: 0 0 2px; background: transparent; font-family: inherit; cursor: pointer; }
.connect-handoff-main { width: min(100%, 760px); flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; margin: 0 auto; padding: 45px 0 90px; text-align: center; }
.connect-handoff-symbol { width: 52px; height: 52px; display: grid; place-items: center; margin: 0 0 29px; }
.connect-handoff-symbol.is-opening { border: 4px solid rgba(248,247,241,.18); border-right-color: #61d8a0; border-radius: 50%; animation: connectWaitSpin .75s linear infinite; }
.connect-handoff-symbol.is-attention { border: 2px solid #e2a43d; border-radius: 50%; color: #e2a43d; font-size: 28px; font-weight: 850; }
.connect-handoff-symbol.is-attention::before { content: '!'; }
.connect-handoff h1 { max-width: 700px; margin: 0; color: #f8f7f1; font-size: clamp(30px, 3.1vw, 44px); font-weight: 800; letter-spacing: -.052em; line-height: 1.06; }
.connect-handoff-main > p { max-width: 580px; margin: 17px 0 0; color: rgba(229,243,235,.72); font-size: clamp(15px, 1.35vw, 18px); line-height: 1.55; }
.connect-handoff-retry { min-height: 58px; margin-top: 34px; border: 0; border-radius: 10px; padding: 14px 30px; background: #24b57a; color: #062217; font: inherit; font-size: 15px; font-weight: 800; cursor: pointer; }
.connect-handoff-retry:hover { background: #61d8a0; }

@media (max-width: 820px) {
    .signup-v1b { display: flex; flex-direction: column; min-height: 100svh; }
    .signup-v1b-pitch { min-height: 263px; padding: 27px 27px 32px; }
    .signup-v1b-brand { font-size: 21px; }
    .signup-v1b-brand img { width: 29px; height: 29px; }
    .signup-v1b-story { margin: auto 0 0; }
    .signup-v1b-story h1 { font-size: clamp(37px, 10vw, 46px); line-height: .96; }
    .signup-v1b-story p, .signup-v1b-signals { display: none; }
    .signup-v1b-main { flex: 1; justify-content: flex-start; padding: 31px 22px 38px; }
    .signup-v1b-form { width: 100%; }
    .signup-v1b-form > h1 { font-size: 26px; }
    .signup-v1b-sub { display: none; }
    .signup-v1b form { gap: 18px; margin-top: 24px; }
    .signup-v1b .field input[type=text], .signup-v1b .field input[type=email], .signup-v1b .field input[type=password], .signup-v1b .field select { min-height: 52px; }
    .signup-v1b .btn.lg { min-height: 52px; }
    .signup-v1b-main.is-personalizing { padding-top: 32px; }
    .signup-v1b-form.signup-personalization { padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; }
    .signup-personalization form { margin-top: 20px; }
    .signup-personalization-body { grid-template-columns: 1fr; gap: 18px; }
    .signup-purpose-grid { grid-template-columns: repeat(3,minmax(0,1fr)); gap: 10px; }
    .signup-personalization .btn.lg { min-height: 54px; }
    .signup-identity-line { margin-top: 0; }
    .signup-purpose > span { min-height: 104px; flex-direction: column; justify-content: center; gap: 5px; padding: 9px 5px; text-align: center; }
    .signup-purpose img { width: 50px; height: 50px; flex-basis: 50px; }
    .signup-purpose b { font-size: 11.5px; }
    .signup-details-grid { grid-template-columns: 1fr; }
    .signup-form-footer { align-items: flex-start; flex-direction: column; gap: 7px; }
    .signup-v1b-google { min-height: 53px; margin-bottom: 18px; }
    .signup-v1b-or { margin-bottom: 18px; }
    .signup-v1b-login { position: static; margin: 22px 0 0; font-size: 13px; }
    .connect-wait { padding: 28px 25px 31px; }
    .connect-wait-brand { font-size: 22px; }
    .connect-wait-link { gap: 10px; margin-bottom: 42px; }
    .connect-wait-link span { padding: 8px 12px; font-size: 11.5px; }
    .connect-wait-link i { width: 64px; }
    .connect-wait-note { font-size: 12px; }
    .connect-scene { padding: 28px 25px 31px; }
    .connect-scene-brand { font-size: 22px; }
    .connect-scene-main { padding-top: 54px; }
    .connect-scene-link { gap: 10px; margin-bottom: 30px; }
    .connect-scene-link span { padding: 8px 12px; font-size: 11.5px; }
    .connect-scene-link i { width: 60px; }
    .connect-title { font-size: 31px; }
    .connect-consent { padding: 21px 20px; }
    .connect-scene-note { font-size: 12px; }
    .connect-handoff { padding: 28px 25px 31px; }
    .connect-handoff-main { padding-bottom: 70px; }
}

@media (max-width: 700px) {
    .wiz-wrap { padding: 18px 14px 28px; }
    .onboarding-flow .wiz-top { padding: 0 2px 18px; }
    .onboarding-flow .wiz-top-right { gap: 0; }
    .onboarding-flow .wiz-back { padding: 8px; font-size: 0; }
    .onboarding-flow .wiz-back svg { width: 17px; height: 17px; }
    .onboarding-flow .wiz-panel { padding: 27px 20px 24px; border-radius: 18px; }
    .onboarding-flow .wiz-crumbs { margin-bottom: 27px; }
    .onboarding-flow .wiz-crumb { font-size: 9.5px; }
    .onboarding-flow .wiz-title { font-size: 27px; }
    .setup-identity, .setup-channel-grid { grid-template-columns: 1fr; }
    .setup-identity { padding: 14px 14px 1px; }
    .setup-trust { flex-direction: column; }
    .setup-facts > .field-row { padding-bottom: 1px; }
}


/* ========================================================================
   Setup (onboarding.php)

   One question a screen, on the same dark green the signup panel uses, so the
   account screen and the first screen after it are one product. The shell is
   the viewport: header, one question, footer, and nothing that scrolls. A step
   that needs more room than the screen has scrolls inside .ob-main only -- the
   footer never leaves, because a wizard whose Continue button is below the
   fold is a wizard people think is broken.

   Everything here is its own ob- component rather than a relit .setup-* or
   .wiz-card. Those were drawn for a white card and every attempt to relight
   them left pale boxes and invisible labels on this ground. */
.ob {
    height: 100dvh;
    display: flex; flex-direction: column;
    background: #0b3024;
    color: #f1efe9;
    overflow: hidden;
}
.ob-top {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between; gap: 20px;
    padding: 30px clamp(22px, 4.6vw, 74px);
}
.ob-brand { color: #f8f7f1; font-size: 23px; font-weight: 800; letter-spacing: -.045em; text-decoration: none; }
.ob-brand:hover { opacity: .82; }
.ob-exit {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px; font-weight: 600; letter-spacing: .17em; text-transform: uppercase;
    color: #8fd9b4; text-decoration: underline; text-underline-offset: 4px;
}
.ob-exit:hover { color: #c3f0d8; }

.ob-main { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; align-items: center; padding: 8px clamp(22px, 4.6vw, 74px) 24px; }
.ob-inner { width: 100%; max-width: 1120px; margin: 0 auto; }
.ob-h { margin: 0 0 14px; color: #f8f7f1; font-size: clamp(30px, 4vw, 54px); font-weight: 760; letter-spacing: -.045em; line-height: 1.04; }
.ob-sub { margin: 0 0 44px; max-width: 62ch; color: #9dc9b3; font-size: 17px; line-height: 1.55; }

/* ---------------------------------------------------------------- fields */
.ob-row { display: grid; grid-template-columns: 1fr 1fr; gap: 34px clamp(36px, 6vw, 84px); }
.ob-inline { display: flex; align-items: flex-end; gap: 28px; }
.ob-inline .ob-field { flex: 1; min-width: 0; }
.ob-field { display: block; margin: 0 0 30px; }
.ob-row .ob-field, .ob-inline .ob-field { margin-bottom: 0; }
.ob-field label {
    display: block; margin-bottom: 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
    color: #7fc3a2;
}
.ob-field input, .ob-field select {
    width: 100%; height: auto; padding: 2px 0 13px;
    border: 0; border-bottom: 1px solid rgba(241,239,233,.26); border-radius: 0;
    background: transparent; color: #f4f2ec;
    font-family: inherit; font-size: 24px; font-weight: 500; letter-spacing: -.015em;
}
.ob-field select {
    appearance: none; padding-right: 32px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239dc9b3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 2px center; background-size: 20px;
}
.ob-field select option { background: #0b3024; color: #f4f2ec; }
.ob-field input::placeholder { color: rgba(241,239,233,.3); }
.ob-field input:focus, .ob-field select:focus, .ob-field textarea:focus { outline: 0; border-color: #3ecf8e; box-shadow: none; }
.ob-field textarea {
    width: 100%; padding: 22px 24px;
    border: 1px solid rgba(241,239,233,.16); border-radius: 16px;
    background: rgba(241,239,233,.05); color: #f4f2ec;
    font-family: inherit; font-size: 17px; line-height: 1.65; resize: none;
}
.ob-field textarea::placeholder { color: rgba(241,239,233,.32); }
.ob-note { margin: 18px 0 0; max-width: 74ch; color: rgba(157,201,179,.85); font-size: 14px; line-height: 1.55; }
.ob-alert { margin: 0 0 28px; padding: 14px 18px; border-radius: 12px; background: rgba(255,138,116,.13); color: #ffdcd3; font-size: 14px; }
.ob-good { margin: 0 0 28px; padding: 14px 18px; border-radius: 12px; background: rgba(62,207,142,.14); color: #b7f0d4; font-size: 14px; }

/* ----------------------------------------------------------------- goals */
.ob-pills { display: flex; flex-wrap: wrap; gap: 13px; margin-top: 46px; }
.ob-pill {
    display: inline-flex; align-items: center; gap: 13px;
    padding: 14px 24px 14px 19px;
    border: 1px solid rgba(241,239,233,.24); border-radius: 999px;
    color: #f1efe9; font-size: 15px; cursor: pointer;
    transition: border-color .15s, background .15s;
}
.ob-pill:hover { border-color: rgba(241,239,233,.5); background: rgba(241,239,233,.05); }
.ob-pill input { position: absolute; opacity: 0; width: 0; height: 0; }
.ob-pill-box {
    position: relative; width: 18px; height: 18px; flex: 0 0 18px;
    border-radius: 5px; background: #f1efe9;
    transition: background .15s;
}
.ob-pill-box::after {
    content: ''; position: absolute; inset: 0;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23062a1c' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center / 12px 12px no-repeat;
    opacity: 0; transform: scale(.4);
    transition: opacity .13s, transform .2s cubic-bezier(.2,1.5,.5,1);
}
.ob-pill input:checked ~ .ob-pill-box { background: #3ecf8e; }
.ob-pill input:checked ~ .ob-pill-box::after { opacity: 1; transform: scale(1); }
.ob-pill input:focus-visible ~ .ob-pill-box { box-shadow: 0 0 0 3px rgba(62,207,142,.45); }
.ob-pill-txt { white-space: nowrap; }

/* --------------------------------------------------------------- buttons */
.ob-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    padding: 15px 30px; border: 0; border-radius: 11px;
    font-family: inherit; font-size: 15px; font-weight: 700; line-height: 1;
    text-decoration: none; cursor: pointer;
    transition: background .15s, border-color .15s, opacity .15s;
}
.ob-btn-1st { background: #2fb47c; color: #06251a; }
.ob-btn-1st:hover { background: #47cd93; color: #06251a; }
.ob-btn-2nd { background: rgba(241,239,233,.1); color: #f1efe9; border: 1px solid rgba(241,239,233,.24); }
.ob-btn-2nd:hover { background: rgba(241,239,233,.17); color: #fff; }
.ob-btn-3rd { background: transparent; color: #f1efe9; border: 1px solid rgba(241,239,233,.3); }
.ob-btn-3rd:hover { background: rgba(241,239,233,.07); color: #fff; border-color: rgba(241,239,233,.55); }
.ob-skip {
    padding: 0; border: 0; background: none; cursor: pointer;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px; color: rgba(157,201,179,.85);
}
.ob-skip:hover { color: #c3f0d8; }

/* ---------------------------------------------------------------- upload */
.ob-upload {
    display: flex; align-items: center; justify-content: space-between; gap: 26px;
    margin-top: 40px; padding: 22px 24px;
    border: 1px dashed rgba(241,239,233,.28); border-radius: 16px;
    cursor: pointer;
}
.ob-upload:hover { border-color: rgba(241,239,233,.5); }
.ob-upload-txt { display: flex; flex-direction: column; gap: 4px; }
.ob-upload-txt b { color: #f8f7f1; font-size: 15px; }
.ob-upload-txt small { color: rgba(157,201,179,.85); font-size: 13px; }
.ob-upload-name { color: #7fe2b0 !important; font-weight: 600; }

/* --------------------------------------------------------------- channels */
.ob-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 22px; }
.ob-card {
    display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
    padding: 30px 32px;
    border: 1px solid rgba(241,239,233,.17); border-radius: 20px;
    background: rgba(241,239,233,.04);
}
.ob-card-wide { max-width: 640px; }
.ob-card-h { color: #f8f7f1; font-size: 20px; font-weight: 700; letter-spacing: -.02em; }
.ob-card-p { margin: 0; color: rgba(157,201,179,.9); font-size: 14.5px; line-height: 1.6; }
.ob-card-state {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 8px 15px; border-radius: 999px;
    background: rgba(62,207,142,.15); color: #8ce7ba;
    font-size: 13px; font-weight: 650;
}
.ob-card .ob-btn { margin-top: 6px; }
.ob-pin { display: flex; align-items: flex-end; gap: 16px; width: 100%; }
.ob-pin .ob-field { flex: 1; margin: 0; }
.ob-pin .ob-field input { font-size: 19px; }

/* Each channel wears its own mark. These are the vendors' real shapes on
   their own brand grounds -- the one place in setup where colour is not the
   product's, because the person is about to hand their account to one of
   them and needs to recognise which. */
.ob-card-ico { width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center; }
.ob-card-ico svg { width: 25px; height: 25px; color: #fff; }
.ob-card-ico.wa { background: #25D366; }
.ob-card-ico.meta { background: #111; }
.ob-ticks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.ob-ticks li {
    position: relative; padding-left: 27px;
    color: rgba(241,239,233,.88); font-size: 14px; line-height: 1.45;
}
.ob-ticks li::before {
    content: ''; position: absolute; left: 0; top: 1px; width: 17px; height: 17px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233ecf8e' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center / 17px 17px no-repeat;
}

/* The house dropdown, relit. .cs is the app's own component (house.js drives
   it); only its colours change here, so a fix to the component still lands. */
.ob .cs-trigger {
    width: 100%; padding: 2px 0 13px;
    border: 0; border-bottom: 1px solid rgba(241,239,233,.26); border-radius: 0;
    background: transparent; color: #f4f2ec;
    font-family: inherit; font-size: 24px; font-weight: 500; letter-spacing: -.015em;
}
.ob .cs-trigger:hover { border-bottom-color: rgba(241,239,233,.5); background: transparent; }
.ob .cs-trigger svg { width: 20px; height: 20px; stroke: #9dc9b3; }
.ob .cs.open .cs-trigger { border-bottom-color: #3ecf8e; }
.ob .cs-panel {
    border: 1px solid rgba(241,239,233,.16); border-radius: 14px;
    background: #10382a; box-shadow: 0 22px 44px rgba(0,0,0,.42);
    padding: 6px;
}
.ob .cs-option { border-radius: 9px; color: #dfeee6; font-size: 15px; }
.ob .cs-option:hover { background: rgba(241,239,233,.09); color: #fff; }
.ob .cs-option.sel { background: rgba(62,207,142,.16); color: #8ce7ba; }

/* ----------------------------------------------------------------- footer */
.ob-foot { flex: 0 0 auto; padding: 0 clamp(22px, 4.6vw, 74px); }
.ob-foot-inner {
    display: flex; align-items: center; gap: 20px;
    padding: 24px 0 30px; border-top: 1px solid rgba(241,239,233,.13);
}
.ob-dots { display: flex; align-items: center; gap: 8px; margin-right: auto; }
.ob-dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(241,239,233,.24); transition: width .2s, background .2s; }
.ob-dot.done { background: rgba(62,207,142,.8); }
.ob-dot.on { width: 26px; border-radius: 999px; background: #3ecf8e; }
.ob-foot-acts { display: flex; align-items: center; gap: 26px; }

@media (max-width: 820px) {
    .ob { height: auto; min-height: 100dvh; overflow: visible; }
    .ob-main { overflow: visible; align-items: flex-start; padding-top: 18px; }
    .ob-h { font-size: 29px; }
    .ob-sub { margin-bottom: 30px; font-size: 15px; }
    .ob-row { grid-template-columns: 1fr; gap: 26px; }
    .ob-inline { flex-direction: column; align-items: stretch; gap: 18px; }
    .ob-field input, .ob-field select { font-size: 19px; }
    .ob-pills { margin-top: 30px; gap: 10px; }
    .ob-pill { padding: 12px 18px 12px 15px; font-size: 14px; }
    .ob-pill-txt { white-space: normal; }
    .ob-upload { flex-direction: column; align-items: stretch; }
    .ob-foot-inner { flex-wrap: wrap; padding-bottom: 22px; }
    .ob-dots { order: 3; width: 100%; justify-content: center; margin: 6px 0 0; }
}

/* ---------------------------------------------------------------------------
 * The new setup flow (Tenant::onboardingFrozen() decides who sees it).
 *
 * Same palette and the same components as the flow above -- .ob-field,
 * .ob-btn, .ob-card and .ob-note are all reused unchanged. What is new here is
 * only what did not exist before: the starter tiles on step 1 and the trial
 * conversation on step 2.
 * ------------------------------------------------------------------------ */

.ob-opt {
    margin-left: 7px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 10px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase;
    color: rgba(157,201,179,.6);
}

/* Step 1's starting points. Buttons, not radios: picking one writes into the
   textarea below and the textarea is the answer -- a checked control still
   sitting there afterwards would claim the choice mattered after the edit. */
.ob-starters { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px; margin: 0 0 30px; }
.ob-starter {
    display: flex; flex-direction: column; gap: 5px;
    padding: 17px 19px; text-align: left; cursor: pointer;
    border: 1px solid rgba(241,239,233,.22); border-radius: 15px;
    background: rgba(241,239,233,.03); color: #f1efe9;
    font: inherit; transition: border-color .13s, background .13s;
}
.ob-starter:hover { border-color: rgba(241,239,233,.5); background: rgba(241,239,233,.07); }
.ob-starter.on { border-color: #3ecf8e; background: rgba(62,207,142,.11); }
.ob-starter b { font-size: 15.5px; font-weight: 650; color: #f8f7f1; }
.ob-starter small { font-size: 13px; line-height: 1.45; color: rgba(157,201,179,.85); }

/* Step 2 is one control: a phone number, and then a way into WhatsApp. It
   lives inside an .ob-card, so all that is needed here is the row itself. */
.ob-real-form { display: flex; gap: 10px; margin-top: 6px; width: 100%; }
.ob-real-form input {
    flex: 1; min-width: 0; padding: 11px 15px;
    border: 1px solid rgba(241,239,233,.2); border-radius: 11px;
    background: rgba(241,239,233,.05); color: #f4f2ec;
    font-family: inherit; font-size: 14.5px;
}
.ob-real-form input::placeholder { color: rgba(241,239,233,.32); }
.ob-real-form input:focus { outline: 0; border-color: #3ecf8e; }
.ob-real-form .ob-btn { padding: 11px 18px; font-size: 14px; }
.ob-real-form .ob-btn:disabled { opacity: .5; cursor: default; }
.ob-real-out { margin-top: 16px; }
.ob-real-out .ob-btn { display: inline-flex; }
.ob-real-bad { color: #ffdcd3; }

/* Account entry: homepage wordmark/canvas and a focused email reveal. */
@font-face { font-family:Citrion; src:url('/assets/fonts/citrion-regular.woff2') format('woff2'); font-weight:400; font-display:swap; }
.signup-v1b { --auth-motion:260ms; --auth-ease:cubic-bezier(.22,1,.36,1); }
.signup-v1b-brand { font-family:Citrion,Inter,serif; font-size:32px; font-weight:400; letter-spacing:-.015em; }
.signup-v1b-main { background:var(--signup-surface); }
.signup-v1b-form.signup-personalization { width:min(100%,520px); padding:0; background:transparent; border:0; box-shadow:none; }
.signup-v1b-signals { border:0; }
.signup-v1b-label { color:#b8d4c6; font-size:13px; letter-spacing:.08em; }
.signup-v1b-pills { gap:22px; }
.signup-v1b-pills .partner-chip { display:inline-flex; width:32px; height:36px; align-items:center; justify-content:center; }
.signup-v1b-pills svg { width:30px; height:30px; }
.signup-v1b-pills .partner-chip--whatsapp { color:#25d366; }
.signup-v1b-pills .partner-chip--messenger { color:#0866ff; }
.signup-v1b-pills .partner-chip--meta { color:#0668e1; }
.signup-v1b-pills .partner-chip--whacl img { width:40px; height:40px; object-fit:contain; }
.signup-v1b .identity-provider { width:100%; min-height:62px; justify-content:center; border:1px solid var(--signup-line); border-radius:999px; background:#fff; color:var(--signup-ink); font-size:16px; gap:14px; text-decoration:none; box-shadow:0 1px 2px rgba(48,59,76,.06); }
.signup-v1b .identity-provider:hover { background:#fff; border-color:#c3ccd8; box-shadow:0 4px 12px -6px rgba(48,59,76,.28); }
.signup-v1b .identity-provider:active { transform:scale(.985); }
.signup-v1b .identity-provider:focus-visible,.auth-email-back:focus-visible { outline:3px solid #147451; outline-offset:4px; }
.signup-v1b .identity-provider svg { width:24px; height:24px; flex:none; }
.signup-v1b .identity-meta { fill:#0668e1; }
.signup-v1b .identity-google { stroke:none; }
.signup-v1b [hidden] { display:none!important; }
.signup-v1b .auth-note { margin-top:22px; color:var(--signup-muted); font-size:13px; line-height:1.6; }
.signup-v1b .auth-note a,.signup-v1b-login a { margin-inline-start:4px; margin-inline-end:4px; }
.signup-v1b-sub { font-size:16px; color:var(--signup-muted); }
.signup-v1b .field label { font-size:14px; }
.signup-v1b .field input[type=email],.signup-v1b .field input[type=password] { font-size:16px; border-radius:18px; }
.signup-v1b .field input:focus { outline:0; box-shadow:none; }
.signup-v1b .field input:focus-visible { outline:3px solid rgba(20,116,81,.3); outline-offset:2px; }
.signup-v1b .btn.lg { border-radius:999px; font-size:16px; min-height:56px; }
.signup-v1b .btn.lg:focus-visible { outline:3px solid rgba(20,116,81,.35); outline-offset:3px; }
.auth-email-back { display:inline-flex; align-items:center; gap:8px; min-height:44px; margin:0 0 20px; padding:0 14px; border:0; border-radius:999px; background:#e0e5eb; color:#202124; font:inherit; cursor:pointer; }
.auth-email-back:hover { background:#d3dae3; }
.auth-email-back:active { transform:scale(.97); }
.auth-enter { animation:auth-enter var(--auth-motion) var(--auth-ease) both; }
@keyframes auth-enter { from { opacity:0; transform:translateX(14px); } to { opacity:1; transform:none; } }
@media(prefers-reduced-motion:reduce) { .auth-enter { animation:none; } }
@media(max-width:700px) { .signup-v1b-pitch { display:flex; min-height:0; padding:22px 24px; } .signup-v1b-story,.signup-v1b-signals { display:none; } .signup-v1b-main,.signup-v1b-main.is-personalizing { padding:40px 24px; min-height:calc(100svh - 85px); justify-content:flex-start; } .signup-v1b-form > h1 { font-size:32px; } }
.signup-v1b-or { margin:24px 0; color:var(--signup-muted); font-size:14px; text-transform:none; letter-spacing:0; }
.signup-v1b-story h1 { font-size:clamp(38px,4vw,54px); }
@media(max-width:820px) {
  .signup-v1b-pitch { min-height:0; padding:22px 24px; }
  .signup-v1b-brand { font-size:32px; line-height:1; }
  .signup-v1b-story,.signup-v1b-signals { display:none; }
  .signup-v1b-main,.signup-v1b-main.is-personalizing { min-height:0; padding:36px 24px 28px; }
  .signup-v1b-form { margin:0 auto; }
  .signup-v1b-sub { display:block; margin-bottom:28px; }
  .signup-v1b-login { margin-top:auto; padding-top:28px; }
  .signup-v1b form { margin-top:0; }
}
.signup-v1b .signup-v1b-main .signup-v1b-form .field .signup-input-shell > input[type=text] { min-width:0; flex:1; width:0; min-height:54px; padding:0; border:0; border-radius:0; background:transparent; box-shadow:none; font-size:16px; }
.signup-v1b .signup-v1b-main .signup-v1b-form .field input[type=email],
.signup-v1b .signup-v1b-main .signup-v1b-form .field input[type=password] { min-height:56px; padding:14px 16px; border:1px solid var(--signup-line); border-radius:18px; background:var(--signup-paper); font-size:16px; }
