/* ─────────────────────────────────────────────────────────────────────────────
   Pro portal dialogs — Claude Design turn 13 ("Pro portal popups — all 12").

   One shell for every popup a professional can see. Values below are taken
   straight from 13a–13d; nothing is approximated.

     desktop (13a–13c)   420px card, radius 12, shadow 0 12px 32px rgba(0,0,0,.14)
     phone   (13d)       bottom sheet, radius 16 16 0 0, grab handle,
                         buttons stacked full-width with the primary on top

   The shape of every dialog is the same four parts, any of which may be absent:
     icon · title · body · [warning strip] · [fact table] · buttons

   The fact table is the reason this redesign matters. Every one of these popups
   asks the pro to commit something — a job, credits, his phone number — and the
   old ones asked with a bare sentence. Naming the job, the fee, the balance
   after, the review time is what turns a yes/no into an informed yes/no.
   ───────────────────────────────────────────────────────────────────────── */

.pd-mask {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(17, 17, 17, .45);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  opacity: 0;
  transition: opacity .18s ease;
}
.pd-mask.in { opacity: 1; }

.pd {
  width: 420px; max-width: 100%;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .14);
  overflow: hidden;
  font-family: 'Inter', system-ui, sans-serif;
  transform: translateY(8px) scale(.98);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1);
  max-height: calc(100dvh - 32px);
  display: flex; flex-direction: column;
}
.pd-mask.in .pd { transform: none; }

.pd-body { padding: 22px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; }

/* icon — 40px tinted circle */
.pd-ico {
  width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font: 400 17px 'Inter', sans-serif;
  flex: none;
}
/* Each is a tint + its own hue (38b). Three of the five were drawn in colours the
   system does not define — #ECFDF5/#059669 and #F0FDF4/#16A34A were two different
   greens for what is one meaning, and .info sat on the disabled fill. */
.pd-ico.good { background: var(--xw-green-tint, #f0fdf4); color: var(--xw-green, #15803d); }
.pd-ico.money{ background: var(--xw-green-tint, #f0fdf4); color: var(--xw-green, #15803d); }
.pd-ico.warn { background: var(--xw-amber-tint, #fffbeb); color: var(--xw-amber, #b45309); }
.pd-ico.bad  { background: var(--xw-red-tint,   #fef2f2); color: var(--xw-red,   #dc2626); }
.pd-ico.info { background: var(--xw-ink-tint,   #f8f9fa); color: var(--xw-text,  #374151); }

.pd-title { font: 600 19px/1.25 'Manrope', system-ui, sans-serif; letter-spacing: -.5px; color: #111; margin: 0; }
.pd-text  { font: 400 12.5px/1.6 'Inter', sans-serif; color: #374151; margin: 0; }

/* The amber consequence strip. It describes a CONDITION and never carries the way
   forward (rule 4) — that stays on the buttons below it. #F59E0B, #FFFBF5, #FEF6F6
   and #991B1B were four colours turn 38 does not define. */
.pd-warn {
  border-left: 3px solid var(--xw-amber, #b45309);
  background: var(--xw-amber-tint, #fffbeb);
  border-radius: 0 8px 8px 0;
  padding: 13px 15px;
  font: 400 11.5px/1.6 'Inter', sans-serif;
  color: var(--xw-amber-dark, #92400e);
}
.pd-warn.bad {
  border-left-color: var(--xw-red, #dc2626);
  background: var(--xw-red-tint, #fef2f2);
  color: var(--xw-red-dark, #b91c1c);
}

/* the fact table — what exactly is being agreed to */
.pd-facts { background: #F8F9FA; border-radius: 8px; padding: 14px; display: flex; flex-direction: column; gap: 9px; }
.pd-facts .r { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.pd-facts .k { font: 400 11.5px 'Inter', sans-serif; color: #6B7280; }
.pd-facts .v { font: 600 11.5px 'Inter', sans-serif; color: #111; text-align: right; }
.pd-facts .v.num  { font: 600 12px 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.pd-facts .v.warn { color: #92400E; }
.pd-facts .v.big  { font: 700 12.5px 'JetBrains Mono', ui-monospace, monospace; }

/* a labelled field (reason box, mobile input) */
.pd-field { display: flex; flex-direction: column; gap: 6px; }
.pd-label {
  font: 500 9.5px 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: .06em; text-transform: uppercase; color: #9CA3AF;
}
.pd-input, .pd-area {
  width: 100%;
  border: 1px solid #E5E7EB; border-radius: 8px;
  padding: 12px 13px;
  font: 400 12.5px 'Inter', sans-serif; color: #111;
  background: #fff;
}
.pd-area { height: 78px; resize: none; }
.pd-input::placeholder, .pd-area::placeholder { color: #9CA3AF; }
.pd-input:focus, .pd-area:focus { outline: none; border-color: #111; }

/* a bulleted "what changed" list (consent dialog) */
.pd-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.pd-list li { position: relative; padding-left: 16px; font: 400 11.5px/1.6 'Inter', sans-serif; color: #374151; }
.pd-list li::before { content: ''; position: absolute; left: 2px; top: 8px; width: 4px; height: 4px; border-radius: 50%; background: #9CA3AF; }

/* A missed required field is ROUTINE, so it is red and never amber — amber has to
   stay rare to keep working (rule 4). Red's text value is #b91c1c. */
.pd-msg { font: 400 11.5px/1.5 'Inter', sans-serif; text-align: center; margin: 0; }
.pd-msg.err { color: #b91c1c; }
.pd-msg.ok  { color: #15803d; }

/* ── buttons ─────────────────────────────────────────────────────────────── */
.pd-foot {
  display: flex; gap: 10px;
  padding-top: 16px; margin-top: 4px;
  border-top: 1px solid #F3F4F6;
}
/* md — 42px, 12px/18px, 8px radius, 600 12.5px (38c). */
.pd-btn {
  flex: 1;
  border-radius: 8px;
  padding: 12px 18px;
  text-align: center;
  font: 600 12.5px 'Inter', sans-serif;
  cursor: pointer;
  border: 1px solid transparent;
  min-height: 42px;
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

/* THE PRIMARY WAS GREEN. The note that used to sit here argued that these dialogs
   are about committing, and green is "go" — but that is the one thing green may
   never be. Rule 2: green reports money and confirmation, and a green primary
   promises the thing already happened. Every dialog in this file asks a
   professional to spend credits, accept a fee, or hand over a number; the button
   was styled as the receipt for a decision he had not made yet.

   INK, not violet, by the pro portal rule (38a): these dialogs put a settled green
   figure directly above the button — "Fee ₹40", "Balance after ₹460" in .pd-facts —
   and on a screen carrying money green the primary is ink. .dark was already ink and
   is kept as an alias so existing call sites keep working. */
.pd-btn.primary,
.pd-btn.dark    { background: #111; color: #fff; border-color: #111; }
/* An outlined cancel is ink OUTLINE, whose text is #111. #374151 is ink's GHOST
   text — using it on a bordered button made Cancel look half-disabled. */
.pd-btn.neutral { background: #fff; color: #111; border-color: #e5e7eb; }
/* DESTROYS, and outlined — rule 3. Filled red is earned only after a typed
   confirmation; see .pd-btn.danger.armed below, which is the only place it is. */
.pd-btn.danger  { background: #fff; color: #b91c1c; border-color: #fecaca; }
@media (hover: hover) {
  .pd-btn.primary:hover,
  .pd-btn.dark:hover    { background: #242424; border-color: #242424; }
  .pd-btn.neutral:hover { background: #f8f9fa; }
  .pd-btn.danger:hover  { background: #fef2f2; border-color: #dc2626; }
}

/* ── the ONE place filled red is legitimate (rule 3) ───────────────────────────
   xwConfirmTwice()'s second step asks the professional to type the word out —
   ERASE, CLOSE — and only then does the button earn its fill. .armed is added by
   pro_dialog.php the moment the typed word matches and removed the moment it stops
   matching; it changes nothing about what the button DOES (the same string
   comparison decides that, as it always has), only whether the control looks like
   it will go through. A red button that is solid before the word is typed is the
   defect rule 3 names; a red button that never fills at all never tells the person
   the gate has opened. */
.pd-btn.danger.armed { background: #dc2626; color: #fff; border-color: #dc2626; }
@media (hover: hover) {
  .pd-btn.danger.armed:hover { background: #b91c1c; border-color: #b91c1c; }
}

/* Disabled is hue-blind (38b) — a faded hue still reads as a hue. */
.pd-btn[disabled] {
  background: #f3f4f6; border-color: #e5e7eb; color: #9ca3af;
  cursor: default; opacity: 1;
}

/* ── phone: 13d bottom sheet ─────────────────────────────────────────────── */
@media (max-width: 640px) {
  .pd-mask { align-items: flex-end; padding: 0; }
  .pd {
    width: 100%;
    /* 14px is the mobile FRAME radius (38c); 16 was this file's own value. */
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -6px 20px rgba(0, 0, 0, .1);
    transform: translateY(100%);
    max-height: calc(100dvh - 40px);
  }
  .pd-mask.in .pd { transform: none; }
  .pd-body { padding: 12px 18px 22px; padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
  .pd-grip { width: 38px; height: 4px; border-radius: 999px; background: #E5E7EB; align-self: center; flex: none; }
  .pd-title { font-size: 17px; letter-spacing: -.4px; }
  .pd-text  { font-size: 12px; line-height: 1.55; }
  /* stacked, primary on top — one thumb, no mis-taps. 38f says the same thing:
     pairs stack, never side by side, and page-level controls go full width. */
  .pd-foot  { flex-direction: column; gap: 10px; padding-top: 12px; margin-top: 0; }
  /* lg — 50px, 15px/22px, 600 14px (38c/38f). Was 48px/14px/13px. */
  .pd-btn   { padding: 15px 22px; font-size: 14px; min-height: 50px; }
}
@media (min-width: 641px) { .pd-grip { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .pd-mask, .pd { transition: none; }
}

/* ── step rail (13 · 8) ─────────────────────────────────────────────────── */
.pd-steps { display: flex; align-items: center; gap: 18px; }
.pd-step {
  display: inline-flex; align-items: center; gap: 7px;
  font: 500 10.5px 'Inter', sans-serif; color: #9CA3AF;
}
.pd-step i {
  width: 18px; height: 18px; border-radius: 50%;
  background: #F3F4F6; color: #9CA3AF;
  font: 500 9.5px/18px 'JetBrains Mono', ui-monospace, monospace;
  text-align: center; font-style: normal; flex: none;
}
.pd-step.on { color: #111; }
.pd-step.on i { background: #111; color: #fff; }

/* ── select ─────────────────────────────────────────────────────────────── */
select.pd-input { appearance: none; background-image: none; cursor: pointer; }

/* ── upload slots (13 · 10) ─────────────────────────────────────────────── */
.pd-slots { display: flex; flex-direction: column; gap: 8px; }
.pd-slot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid #E5E7EB; border-radius: 8px;
  padding: 12px 13px; cursor: pointer;
}
.pd-slot .n { font: 500 12px 'Inter', sans-serif; color: #111; }
.pd-slot .b { font: 500 11px 'Inter', sans-serif; color: #6B7280; }
/* "Selected" REPORTS that a file is now attached — a fact, which is what green is
   for. #16A34A is not the defined green; #15803d is. */
.pd-slot .b.done { color: #15803d; }
@media (hover: hover) { .pd-slot:hover { background: #F8F9FA; } }

/* ── agree checkbox (13 · 9) ────────────────────────────────────────────── */
/* 18×18 and violet: a checked box FILLS with its hue, and the hue for a choice the
   person is making — agreeing to terms — is violet, not the green of a settled
   fact (38e). */
.pd-check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.pd-check input { width: 18px; height: 18px; margin: 1px 0 0; accent-color: #7c3aed; flex: none; }
.pd-check span { font: 400 11.5px/1.55 'Inter', sans-serif; color: #374151; }

.pd-hint { font: 400 10.5px/1.55 'Inter', sans-serif; color: #9CA3AF; margin: 0; }

/* the quiet escape under the buttons — "I will explore the app first" */
/* An ink GHOST, whose text is #374151 (38b). It was #9CA3AF — the colour the system
   uses for disabled text and counts — so the one escape route out of the dialog
   looked like it was switched off. */
.pd-textlink {
  background: none; border: 0; width: 100%;
  padding: 10px 0 0; margin: 0;
  font: 600 12.5px 'Inter', sans-serif; color: #374151; cursor: pointer;
}
@media (hover: hover) { .pd-textlink:hover { color: #111; } }

/* ── the grace popups (13 · 9–12) ────────────────────────────────────────────
   These four are shown by removing Tailwind's .hidden rather than by the
   dialog engine, so they need two things the engine handles itself:

   1. .pd-mask sets display:flex and pro_dialog.css loads AFTER tw.css, so it
      would beat .hidden{display:none} and every grace popup would be stuck open
      on every page. Explicitly lose to .hidden.
   2. They never get the .in class that drives the fade, so without .pd-static
      they would sit at opacity:0 — visible to a screen reader, invisible to a
      person, and blocking every click on the page. */
.pd-mask.hidden { display: none !important; }
.pd-mask.pd-static { opacity: 1; }
.pd-mask.pd-static .pd { transform: none; }

/* They are taller than a confirm dialog, so let their body scroll. */
.pd-mask.pd-static .pd-body { max-height: calc(100dvh - 64px); overflow-y: auto; }


/* Caller-mounted content (o.node). Spaced like the built-in blocks so a dialog
   with a custom body still reads as one stack. */
.pd-body #pd-node:empty { display: none; }
.pd-body #pd-node > * + * { margin-top: 12px; }
