/* Bailee widget styles. Tokens only — no new colours.
   Scoped under .widget so page styles are untouched. */
@import url('../tokens.css?v=3');
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');

.widget{
  font-family:var(--font-body);
  color:var(--ink);
  background:var(--panel-bg);
  border:1px solid var(--border-hairline);
  border-radius:var(--radius-lg,22px);
  padding:22px 24px 20px;
  margin:16px 0;
  position:relative;
  overflow:hidden;
  backdrop-filter:blur(8px);
}
.widget::before{
  content:'';position:absolute;inset:-40% 40% 60% -20%;pointer-events:none;
  background:radial-gradient(60% 60% at 30% 40%,var(--fx-halo-b),transparent 70%);
}
.widget > *{position:relative}

.widget h2{font-size:1.4rem;font-weight:600;margin:0 0 6px;letter-spacing:-.01em;line-height:1.25}
.widget h3{font-size:.95rem;font-weight:600;margin:0 0 9px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--fg-muted);line-height:1.4}
.widget p{margin:0 0 11px;color:var(--fg-muted);font-size:1.05rem;line-height:1.6}
.widget .lede{margin-bottom:16px}
.widget a{color:var(--accent)}
.widget hr{border:0;border-top:1px solid var(--border-hairline);margin:16px 0}

/* ---- panels ---- */
.widget .panel{
  background:var(--chip-bg);border:1px solid var(--border-hairline);
  border-radius:var(--radius);padding:16px 18px;
}
.widget .panel + .panel{margin-top:12px}
.widget .cols{display:grid;gap:14px;grid-template-columns:1fr 1fr}
.widget .cols3{display:grid;gap:14px;grid-template-columns:repeat(3,1fr)}
@media (max-width:760px){.widget .cols,.widget .cols3{grid-template-columns:1fr}}

.widget .panel.chain{border-color:color-mix(in srgb,var(--accent) 45%,transparent)}
.widget .panel.local{border-color:color-mix(in srgb,var(--tint-lime) 45%,transparent)}
.widget .panel.chain h3{color:var(--accent)}
.widget .panel.local h3{color:var(--tint-lime)}

/* ---- form controls ---- */
.widget label{display:block;font-size:.95rem;letter-spacing:.07em;text-transform:uppercase;
  color:var(--fg-muted);margin:0 0 9px;line-height:1.45}
.widget .field{margin-bottom:14px}
.widget input,.widget select,.widget textarea{
  width:100%;box-sizing:border-box;background:var(--neutral-950);color:var(--ink);
  border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
  padding:10px 13px;font-family:var(--font-body);font-size:1rem;line-height:1.45;
}
.widget textarea{font-family:var(--font-mono);font-size:1rem;line-height:1.6;resize:vertical}
.widget input[type=file]{padding:9px;font-size:.95rem}
.widget input:focus,.widget select:focus,.widget textarea:focus{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.widget .inline{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end}
.widget .inline > *{flex:1 1 160px}
.widget .inline > .btn{flex:0 0 auto}

.widget .btn{
  display:inline-flex;align-items:center;gap:8px;cursor:pointer;
  background:var(--accent);color:#04070f;border:1px solid transparent;
  border-radius:999px;padding:10px 20px;font-family:var(--font-body);
  font-weight:600;font-size:.95rem;line-height:1.2;transition:background .15s,transform .05s;
}
.widget .btn:hover{background:var(--accent-hover)}
.widget .btn:active{transform:translateY(1px)}
.widget .btn[disabled]{opacity:.45;cursor:not-allowed}
.widget .btn.ghost{background:transparent;color:var(--ink);border-color:var(--border-hairline)}
.widget .btn.ghost:hover{border-color:var(--accent);color:var(--accent)}
.widget .actions{display:flex;gap:10px;flex-wrap:wrap;margin:12px 0 0}

/* ---- mono, chips, status ---- */
.widget code,.widget .mono{font-family:var(--font-mono);font-size:.95rem;line-height:1.6;word-break:break-all}
.widget .monoblock{
  background:var(--neutral-950);border:1px solid var(--border-hairline);
  border-radius:var(--radius-sm);padding:11px 13px;margin:8px 0;cursor:pointer;
  transition:border-color .15s;
}
.widget .monoblock:hover{border-color:var(--accent)}
.widget .monoblock.copied{border-color:var(--tint-lime)}
.widget .mb-label{display:block;font-size:.95rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--fg-muted);margin-bottom:9px;line-height:1.45}
.widget .monoblock code{color:var(--brand-200)}

.widget .chip{display:inline-block;background:var(--chip-bg);border:1px solid var(--border-hairline);
  border-radius:999px;padding:5px 13px;font-size:.95rem;line-height:1.4;color:var(--fg-muted);margin:0 6px 6px 0}
.widget .chip.on{border-color:var(--accent);color:var(--accent)}

.widget .kv{display:flex;gap:14px;justify-content:space-between;align-items:baseline;
  padding:9px 0;border-bottom:1px dashed var(--border-hairline)}
.widget .kv:last-child{border-bottom:0}
.widget .kv .k{font-size:.95rem;letter-spacing:.05em;text-transform:uppercase;color:var(--fg-muted);
  flex:0 0 auto;line-height:1.5}
.widget .kv .v{text-align:right;font-size:1rem;line-height:1.5;word-break:break-word}
.widget .kv .v.mono{font-family:var(--font-mono);font-size:.95rem;color:var(--brand-200)}

.widget .ok{color:var(--tint-lime)}
.widget .bad{color:var(--tint-ember)}
.widget .warn{color:var(--tint-ice)}
.widget .muted{color:var(--fg-muted)}
.widget .verdict{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border-radius:var(--radius);
  border:1px solid var(--border-hairline);background:var(--neutral-950);margin:0 0 12px;font-size:1rem;line-height:1.55}
.widget .verdict.pass{border-color:color-mix(in srgb,var(--tint-lime) 55%,transparent)}
.widget .verdict.fail{border-color:color-mix(in srgb,var(--tint-ember) 55%,transparent)}
.widget .verdict .mark{font-size:1.1rem;line-height:1.3}
.widget .verdict strong{display:block;font-size:1.05rem;margin-bottom:3px;color:var(--ink)}

/* ---- tables ---- */
.widget table{width:100%;border-collapse:collapse;font-size:1rem;line-height:1.55;margin:6px 0 0}
.widget th{text-align:left;font-size:.95rem;letter-spacing:.09em;text-transform:uppercase;line-height:1.4;
  color:var(--fg-muted);font-weight:500;padding:11px 14px;border-bottom:1px solid var(--border-hairline)}
.widget td{padding:12px 14px;border-bottom:1px solid var(--border-hairline);vertical-align:top}
.widget tr:last-child td{border-bottom:0}
.widget td.num,.widget th.num{text-align:right;font-family:var(--font-mono);font-size:.95rem}
.widget tfoot td{font-weight:600;border-top:1px solid var(--border-hairline)}

/* ---- merkle / proof path ---- */
.widget .tree{display:flex;flex-direction:column;gap:7px;font-family:var(--font-mono);font-size:.95rem}
.widget .tree .lvl{display:flex;gap:6px;flex-wrap:wrap}
.widget .node{background:var(--neutral-950);border:1px solid var(--border-hairline);
  border-radius:8px;padding:5px 9px;color:var(--fg-muted)}
.widget .node.path{border-color:var(--accent);color:var(--accent)}
.widget .node.self{border-color:var(--tint-lime);color:var(--tint-lime)}

/* ---- certificate (printable) ---- */
.widget .cert{background:var(--neutral-950);border:1px solid var(--border-hairline);
  border-radius:var(--radius);padding:24px 28px;margin-top:14px}
.widget .cert .seal{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;
  border-bottom:1px solid var(--border-hairline);padding-bottom:16px;margin-bottom:18px}
.widget .cert .seal h4{margin:0 0 5px;font-size:1.14rem;font-weight:600;letter-spacing:-.01em}
.widget .cert .seal .sub{font-size:1rem;color:var(--fg-muted);letter-spacing:.03em;line-height:1.55}
.widget .cert .claim{display:flex;gap:12px;padding:12px 0;border-bottom:1px dashed var(--border-hairline)}
.widget .cert .claim:last-of-type{border-bottom:0}
.widget .cert .claim .n{flex:0 0 30px;height:30px;border-radius:999px;border:1px solid var(--accent);
  color:var(--accent);display:flex;align-items:center;justify-content:center;font-size:1rem}
.widget .cert .claim .t{font-size:1.02rem;line-height:1.5;margin:2px 0 5px}
.widget .cert .claim .e{font-size:1rem;color:var(--fg-muted);font-family:var(--font-mono);line-height:1.6}
.widget .cert .foot{margin-top:16px;padding-top:13px;border-top:1px solid var(--border-hairline);
  font-size:1rem;color:var(--fg-muted);font-family:var(--font-mono);line-height:1.65;word-break:break-all}

@media print{
  html body{background:#fff}
  .widget{border:0;background:none;backdrop-filter:none;padding:0}
  .widget::before{display:none}
  .widget .noprint,.widget .actions,.widget .btn,.widget form,.widget .panel.builder{display:none!important}
  .widget .cert{border:1px solid #333;color:#000;background:#fff}
  .widget .cert *{color:#000!important}
  .widget .cert .claim .n{border-color:#333}
}

.widget .note{font-size:1rem;color:var(--fg-muted);line-height:1.6;
  border-left:2px solid var(--accent);padding:2px 0 2px 13px;margin:13px 0}
.widget .bignum{font-family:var(--font-mono);font-size:1.6rem;color:var(--ink);letter-spacing:-.02em}
.widget .bignum small{display:block;font-family:var(--font-body);font-size:.95rem;
  letter-spacing:.08em;text-transform:uppercase;color:var(--fg-muted);margin-top:7px;line-height:1.45}
.widget .code-readout{font-family:var(--font-mono);font-size:1.1rem;letter-spacing:.04em;
  color:var(--accent);line-height:1.8;word-break:break-all}

/* ---- phones: tables scroll instead of being clipped by .widget overflow ---- */
@media (max-width:560px){
  .widget{padding:18px 15px}
  .widget table{display:block;width:100%;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
  .widget .kv{flex-direction:column;align-items:flex-start;gap:2px}
  .widget .kv .v{text-align:left}
  .widget .cert{padding:20px 16px}
  .widget .code-readout{font-size:.98rem}
}

/* ---- workplace console (app/workplace.js) ------------------------------
   Prefixed .wp-* and scoped under .widget, so nothing above is touched.
   Tokens only, same palette as every other widget. */
.widget .wp-bar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin:0 0 16px}

/* THE ROLE SWITCH — this is the one thing the console exists to show, so it is
   the loudest control on the page: a real segmented switch, an accent-filled
   active side, a VIEWING badge, and a line saying whose eyes you are using.
   Markup comes from app/workplace.js (unchanged):
     <div class="wp-switch" role="group"><button class="on" data-role="client">
   Everything below is CSS only. */
.widget .wp-switch{display:inline-flex;gap:4px;padding:4px;
  border:1px solid var(--accent-ring);border-radius:999px;background:var(--neutral-950);
  box-shadow:0 0 0 1px var(--accent-ring),0 20px 44px -30px var(--fx-glow)}
.widget .wp-switch button{cursor:pointer;border:0;border-radius:999px;padding:13px 22px;
  display:inline-flex;align-items:center;gap:9px;
  background:transparent;color:var(--fg-muted);font-family:var(--font-body);
  font-size:1.06rem;font-weight:500;line-height:1.2;letter-spacing:-.01em;
  transition:background .15s,color .15s}
/* the off side reads as an empty radio, the on side as a filled one */
.widget .wp-switch button::before{content:'';width:11px;height:11px;border-radius:999px;
  border:1.5px solid currentColor;flex:0 0 auto;opacity:.6}
.widget .wp-switch button:hover{color:var(--ink);background:var(--chip-bg)}
.widget .wp-switch button.on{background:var(--accent);color:#04070f;font-weight:700}
.widget .wp-switch button.on::before{background:#04070f;border-color:#04070f;opacity:1}
.widget .wp-switch button.on::after{content:'VIEWING';font-family:var(--font-mono);
  font-size:.95rem;font-weight:500;letter-spacing:.12em;line-height:1.4;padding:3px 10px;border-radius:999px;
  background:color-mix(in srgb,#04070f 20%,transparent);color:#04070f}

/* whose eyes you are looking through. Generated from the switch state, so it
   cannot drift out of step with the buttons. If app/workplace.js starts
   emitting its own .wp-viewline inside .wp-bar, this one steps aside. */
.widget .wp-bar::after{order:99;flex:1 1 100%;margin:2px 0 0;
  font-size:.98rem;line-height:1.5;color:var(--fg-muted)}
.widget .wp-bar:not(:has(.wp-viewline)):has(button[data-role="client"].on)::after{
  content:'You are looking through the client\2019s eyes. Unsent drafts and lawyer-only notes are not in this view.'}
.widget .wp-bar:not(:has(.wp-viewline)):has(button[data-role="lawyer"].on)::after{
  content:'You are looking through the lawyer\2019s eyes. Drafts, holds and the full log are visible here.'}
/* .wp-viewline — for the widget-JS worker, if they would rather write the line
   in markup than have CSS generate it. Same look, no duplicate. */
.widget .wp-viewline{flex:1 1 100%;margin:2px 0 0;font-size:.98rem;line-height:1.5;
  color:var(--fg-muted)}
.widget .wp-viewline b{color:var(--ink);font-weight:500}
@media (max-width:560px){
  .widget .wp-switch{width:100%}
  .widget .wp-switch button{flex:1 1 0;justify-content:center;padding:13px 10px;font-size:1rem}
  .widget .wp-switch button.on::after{display:none}
}
.widget .wp-bar .btn{padding:10px 16px}

/* the rail: a stage lights when an event happened, never when a button was pressed */
.widget .wp-rail{display:flex;gap:0;list-style:none;padding:0;margin:0 0 16px;flex-wrap:wrap}
.widget .wp-stage{flex:1 1 132px;position:relative;padding:0 12px 0 0;min-width:0}
.widget .wp-stage b{display:block;font-size:.95rem;font-weight:500;color:var(--fg-muted);
  letter-spacing:.01em;line-height:1.35;margin-top:9px}
.widget .wp-stage small{display:block;font-size:.95rem;color:var(--fg-muted);opacity:.8;
  line-height:1.5;margin-top:5px}
.widget .wp-dot{display:block;width:10px;height:10px;border-radius:999px;
  border:1px solid var(--border-hairline);background:var(--neutral-950)}
.widget .wp-stage::before{content:'';position:absolute;left:10px;right:0;top:4px;height:1px;
  background:var(--border-hairline)}
.widget .wp-stage:last-child::before{display:none}
.widget .wp-stage.is-done .wp-dot{background:var(--tint-lime);border-color:var(--tint-lime)}
.widget .wp-stage.is-done b{color:var(--ink)}
.widget .wp-stage.is-next .wp-dot{border-color:var(--accent)}
.widget .wp-stage.is-next b{color:var(--accent)}

/* the thread */
.widget .wp-thread{max-height:520px;overflow-y:auto}
.widget .wp-sub{font-size:1rem;line-height:1.55;color:var(--fg-muted);margin:0 0 11px}
.widget .wp-msg{border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
  padding:12px 14px;margin:0 0 10px;background:var(--neutral-950)}
.widget .wp-msg p{margin:0;font-size:1.06rem;color:var(--ink);line-height:1.6}
.widget .wp-msg.wp-client{border-left:2px solid var(--tint-lime)}
.widget .wp-msg.wp-lawyer{border-left:2px solid var(--accent)}
.widget .wp-msg.wp-unsent{border-style:dashed;border-left:2px solid var(--tint-ember)}
.widget .wp-msg.wp-void{border-style:dashed;opacity:.7}
.widget .wp-msg.wp-void p{color:var(--fg-muted);font-style:italic}
.widget .wp-attrib{display:flex;gap:8px;justify-content:space-between;align-items:baseline;
  flex-wrap:wrap;margin:0 0 7px}
.widget .wp-attrib b{font-size:1rem;font-weight:600;letter-spacing:.03em;color:var(--ink)}
.widget .wp-chips .chip{margin:0 0 0 5px;padding:4px 10px}
.widget .wp-hold{margin-top:9px;padding:7px 10px;border-radius:var(--radius-sm);
  background:color-mix(in srgb,var(--tint-ember) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--tint-ember) 40%,transparent);
  font-size:1rem;color:var(--fg-muted);line-height:1.55}
.widget .wp-hold b{color:var(--tint-ember)}
.widget .wp-sendrow{display:flex;gap:7px;flex-wrap:wrap;align-items:center;margin-top:9px}
.widget .wp-sendrow .btn{padding:9px 16px}
.widget .wp-sendrow .wp-kind{width:auto;flex:0 0 auto;padding:9px 11px}
.widget .wp-foot{margin-top:9px;font-size:.98rem;line-height:1.55;color:var(--fg-muted)}
.widget .wp-foot .mono{font-size:.98rem}

/* documents, connect, close, log */
.widget .wp-compose textarea{margin-bottom:0}
.widget .wp-compose .actions{margin-top:12px}
.widget .wp-compose .btn{padding:9px 17px}
.widget .wp-docs,.widget .wp-connect,.widget .wp-close,.widget .wp-loglist{margin-top:14px}
.widget .wp-docs .btn{padding:9px 16px}
.widget .wp-path{display:block;font-size:.98rem;color:var(--fg-muted);line-height:1.55;margin-top:6px}
.widget .wp-loglist ul{list-style:none;margin:0;padding:0}
.widget .wp-loglist li{font-size:1rem;color:var(--fg-muted);padding:8px 0;
  border-bottom:1px dashed var(--border-hairline);line-height:1.55}
.widget .wp-loglist li:last-child{border-bottom:0}
.widget .wp-loglist li .mono{color:var(--fg-muted);opacity:.72;margin-right:8px;font-size:.95rem}
.widget .wp-log-refused{color:var(--tint-ember)}
.widget .wp-log-ok{color:var(--fg-muted)}

@media (max-width:760px){
  .widget .wp-stage{flex:1 1 46%;padding-bottom:10px}
  .widget .wp-thread{max-height:none}
}


/* =========================================================================
   .wm-*  —  "pick an example, or write your own" input kit
   -------------------------------------------------------------------------
   WHO OWNS WHAT
     CSS (these rules)   : UI worker  (site/app/app.css, site/style.css)
     MARKUP that uses it : widget-JS worker (site/app/*.js) — the dropdowns
                           that replace the pre-filled demo inputs.
   Nothing here is used by app.css itself; it exists for the JS to emit.

   SHAPE THE CSS EXPECTS
     <div class="wm-field">
       <label for="wm-model">Model</label>
       <select class="wm-select" id="wm-model">
         <option value="claude-3-5-sonnet">claude-3-5-sonnet</option>
         <option value="gpt-4o">gpt-4o</option>
         <option value="__own">Write my own&hellip;</option>
       </select>
       <button type="button" class="wm-own" hidden>Write my own</button>
       <input class="wm-input" id="wm-model-own" type="text"
              placeholder="Type any model name" hidden>
       <p class="wm-hint">Anything you type is hashed in this browser. It does not leave.</p>
     </div>

   RULES
     - reveal by removing the `hidden` attribute; [hidden] is honoured below
       even on the flex/inline-flex members, so no inline display juggling.
     - .wm-select and .wm-input inherit the widget input look, so they still
       match at the new type size (1rem / 17px) with a 44px touch target.
     - one .wm-field per labelled control; it brings its own bottom margin.
     - usable at 360px: everything is full width and stacks.
   ========================================================================= */

.widget .wm-field{margin:0 0 16px;min-width:0}
.widget .wm-field > label{display:block;font-size:.95rem;letter-spacing:.07em;
  text-transform:uppercase;color:var(--fg-muted);margin:0 0 9px;line-height:1.45}

.widget .wm-select{
  width:100%;box-sizing:border-box;min-height:44px;
  background:var(--neutral-950);color:var(--ink);
  border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
  padding:10px 40px 10px 13px;
  font-family:var(--font-body);font-size:1rem;line-height:1.45;
  -webkit-appearance:none;appearance:none;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%239BA7B4' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 8l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 12px center;background-size:16px 16px;
}
.widget .wm-select:hover{border-color:var(--accent-ring)}
.widget .wm-select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.widget .wm-select option{background:var(--neutral-950);color:var(--ink);font-size:1rem}

/* the "Write my own" escape hatch: a quiet row under the dropdown, not a
   second primary button competing with the widget's real action */
.widget .wm-own{
  display:inline-flex;align-items:center;gap:8px;
  margin:8px 0 0;padding:7px 13px;min-height:36px;
  background:transparent;color:var(--fg-muted);
  border:1px dashed var(--border-hairline);border-radius:999px;
  font-family:var(--font-body);font-size:.95rem;line-height:1.2;cursor:pointer;
  transition:color .15s,border-color .15s;
}
.widget .wm-own::before{content:'+';font-family:var(--font-mono);font-size:1rem;line-height:1}
.widget .wm-own:hover{color:var(--accent);border-color:var(--accent)}
.widget .wm-own.on{color:var(--accent);border-style:solid;border-color:var(--accent)}

.widget .wm-input{
  width:100%;box-sizing:border-box;min-height:44px;
  margin:8px 0 0;
  background:var(--neutral-950);color:var(--ink);
  border:1px solid var(--accent-ring);border-radius:var(--radius-sm);
  padding:10px 13px;font-family:var(--font-body);font-size:1rem;line-height:1.45;
}
.widget .wm-input::placeholder{color:var(--fg-muted);opacity:.75}
.widget .wm-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.widget .wm-input.mono{font-family:var(--font-mono);font-size:1rem}

.widget .wm-hint{
  margin:8px 0 0;color:var(--fg-muted);
  font-size:.98rem;line-height:1.55;
}
.widget .wm-hint b,.widget .wm-hint strong{color:var(--ink);font-weight:500}

/* hiding must beat the display values above */
.widget .wm-field[hidden],.widget .wm-select[hidden],
.widget .wm-own[hidden],.widget .wm-input[hidden],
.widget .wm-hint[hidden]{display:none !important}

/* -------------------------------------------------------------------------
   IN-DROPDOWN "Write my own" (certificate builder, app/certificate.js)
   "Write my own" is the last OPTION in the <select>, not a button beside it.
   The field is therefore: label row, select, one hidden box. The box is
   revealed by the JS clearing its inline display:none, same as before.
   .wm-own above is kept for the widgets that still emit the button form.
   ------------------------------------------------------------------------- */

/* the field is the positioning context for its explainer */
.widget .wm-field{position:relative}

/* a plain box the reader always types into: no dropdown, nothing pre-filled.
   Same metrics as .wm-select so a text field and a dropdown line up. */
.widget .wm-text{
  width:100%;box-sizing:border-box;min-height:44px;
  background:var(--neutral-950);color:var(--ink);
  border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
  padding:10px 13px;font-family:var(--font-body);font-size:1rem;line-height:1.45;
}
.widget .wm-text::placeholder{color:var(--fg-muted);opacity:.7;font-style:italic}
.widget .wm-text:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)}
.widget .wm-text.mono{font-family:var(--font-mono)}

/* a value the deployment supplies, not a control: readable, obviously not editable */
.widget .wm-fixed{
  display:block;width:100%;box-sizing:border-box;min-height:44px;
  background:transparent;color:var(--ink);
  border:1px dashed var(--border-hairline);border-radius:var(--radius-sm);
  padding:10px 13px;font-family:var(--font-body);font-size:1rem;line-height:1.45;
}

/* =========================================================================
   .wm-q / .wm-tip  —  the "?" explainer
   -------------------------------------------------------------------------
   Requirements it has to meet, all of them:
     - opens on :hover AND on :focus-visible, so a keyboard reaches it
       (:focus is kept as well for browsers without :focus-visible)
     - aria-describedby ties the "?" to .wm-tip; the tooltip text is the
       description, so a screen reader reads the same words the mouse gets
     - never covers the control it describes: it is anchored BELOW the whole
       .wm-field, so the label and the input stay readable while it is open
     - cannot fall off a narrow screen: left:0/right:0 inside the field, so
       it is exactly as wide as the control and wraps instead of overflowing
     - pointer-events:none, so it can never swallow a click meant for the
       field underneath it
     - .98rem, the same size as .wm-hint: an explainer must not be the
       smallest text on the page
   ========================================================================= */

.widget .wm-labelrow{
  display:flex;align-items:center;gap:7px;
  margin:0 0 9px;min-width:0;
}
.widget .wm-labelrow > label,.widget .wm-labelrow > .wm-computed-t{
  display:block;margin:0;font-size:.95rem;letter-spacing:.07em;
  text-transform:uppercase;color:var(--fg-muted);line-height:1.45;
}

.widget .wm-help{position:static;display:inline-flex;align-items:center;flex:0 0 auto}

.widget .wm-q{
  display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;padding:0;flex:0 0 auto;
  background:transparent;color:var(--fg-muted);
  border:1px solid var(--border-hairline);border-radius:999px;
  font-family:var(--font-body);font-size:.85rem;line-height:1;font-weight:600;
  cursor:help;transition:color .15s,border-color .15s;
}
.widget .wm-q:hover{color:var(--accent);border-color:var(--accent)}
.widget .wm-q:focus{outline:none;color:var(--accent);border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-ring)}

.widget .wm-tip{
  display:none;position:absolute;z-index:30;
  left:0;right:0;top:100%;margin-top:6px;
  max-width:100%;box-sizing:border-box;
  background:var(--neutral-950);color:var(--ink);
  border:1px solid var(--accent-ring);border-radius:var(--radius-sm);
  padding:11px 13px;
  font-family:var(--font-body);font-size:.98rem;line-height:1.55;
  text-transform:none;letter-spacing:normal;font-weight:400;
  box-shadow:0 10px 30px rgba(0,0,0,.45);
  pointer-events:none;                 /* never blocks the control it explains */
}
.widget .wm-q:hover + .wm-tip,
.widget .wm-help:hover .wm-tip,
.widget .wm-q:focus + .wm-tip,
.widget .wm-q:focus-visible + .wm-tip{display:block}

/* the three digests the demo computes: not inputs, but they still get a "?" */
.widget .wm-computed{border-top:1px dashed var(--border-hairline);padding-top:12px;margin-top:4px}
.widget .wm-computed-i{display:inline-flex;align-items:center;gap:6px;margin-right:14px;color:var(--ink)}

/* room under the last row so an explainer is never cut off by .widget's overflow */
.widget .builder{padding-bottom:30px}

@media (max-width:560px){
  .widget .wm-labelrow{flex-wrap:nowrap}
  .widget .wm-tip{font-size:1rem}
  .widget .wm-computed-i{display:flex;margin:0 0 6px}
}

/* two controls side by side collapse to one column on a phone */
.widget .wm-row{display:grid;gap:14px;grid-template-columns:1fr 1fr}
@media (max-width:560px){
  .widget .wm-row{grid-template-columns:1fr}
  .widget .wm-own{width:100%;justify-content:center}
  .widget .wm-select{padding-right:38px}
}

/* =========================================================================
   .ct-warn  —  "these fields are blank" (certificate builder, app/certificate.js)
   -------------------------------------------------------------------------
   Kevin's rule: sign N/A on anything missing, but always warn first. So this is
   a confirmation, not fine print, and not a block:
     - role="alertdialog", tabindex="-1", focused when it opens, Escape cancels
     - both choices are real .btn buttons, so the keyboard reaches them and they
       read the same as every other action in the widget
     - body text is 1.02rem, no smaller than .wm-hint: a warning nobody can read
       is a warning nobody gets
     - it lives in the widget, inside .panel.builder, so print hides it with the
       rest of the form and no browser setting can suppress it
   ========================================================================= */

.widget .ct-warn{
  margin:14px 0 0;padding:15px 17px;
  background:var(--neutral-950);
  border:1px solid color-mix(in srgb,var(--tint-ember) 55%,transparent);
  border-radius:var(--radius);
}
.widget .ct-warn:focus{outline:none;box-shadow:0 0 0 3px var(--accent-ring)}
.widget .ct-warn h4{
  display:flex;align-items:center;gap:9px;
  margin:0 0 8px;font-size:1.08rem;font-weight:600;color:var(--ink);line-height:1.35;
}
.widget .ct-warn-mark{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:24px;height:24px;border-radius:999px;
  border:1px solid var(--tint-ember);color:var(--tint-ember);
  font-size:1rem;font-weight:600;line-height:1;
}
.widget .ct-warn p{margin:0 0 10px;color:var(--ink);font-size:1.02rem;line-height:1.6}
.widget .ct-warn-list{
  list-style:none;margin:0 0 12px;padding:0;
  border-top:1px dashed var(--border-hairline);
}
.widget .ct-warn-list li{
  display:flex;gap:14px;justify-content:space-between;align-items:baseline;flex-wrap:wrap;
  padding:8px 0;border-bottom:1px dashed var(--border-hairline);
  font-size:1.02rem;line-height:1.5;
}
.widget .ct-warn-f{color:var(--ink)}
.widget .ct-warn-r{color:var(--tint-ember);font-family:var(--font-mono);font-size:.98rem}
.widget .ct-warn .actions{margin:0}
.widget .ct-warn-foot{margin:10px 0 0;color:var(--fg-muted);font-size:.98rem}

/* =========================================================================
   .cert-na  —  a field nobody answered, on the issued certificate
   A court reading it has to be able to tell at a glance what was not stated,
   so N/A is marked wherever it appears and listed once at the top. The mark is
   a dotted underline in the current ink, so it survives the print rule that
   forces every colour in .cert to black.
   ========================================================================= */

.widget .cert-na{
  color:var(--tint-ember);font-weight:600;
  border-bottom:1px dotted currentColor;
  white-space:nowrap;
}
.widget .cert .cert-na-banner{
  margin:0 0 14px;padding:10px 13px;
  border:1px dashed color-mix(in srgb,var(--tint-ember) 55%,transparent);
  border-radius:var(--radius-sm);
  color:var(--ink);font-size:1rem;line-height:1.6;
}
.widget .cert .cert-na-banner strong{color:var(--tint-ember)}

@media print{
  .widget .cert .cert-na-banner{border:1px dashed #333}
  .widget .cert .cert-na{border-bottom:1px dotted #000}
}

/* =========================================================================
   .ct-cite  —  claim 3, checked (certificate builder, app/certificate.js)
   -------------------------------------------------------------------------
   The two counts under claim 3 used to be whatever somebody typed. This is the
   control that goes and looks: a passage, one button, and a verdict per citation
   with a link to the case on CourtListener where there is one.
     - it is a box of its own inside the builder, because it is a different kind
       of act from filling a field in: it leaves the page and asks somebody
     - one row per citation, verdict in its own column, so "not found" is read at
       a glance and not hunted for in a sentence
     - .ok / .bad / .warn already carry the widget's three states; the rows only
       add the rule down the left, so a colour-blind reader still has position
     - a locked count still looks like a value, not like a disabled control: it
       was filled in by a real lookup, which is more than a typed one ever was
   ========================================================================= */

.widget .ct-cite{
  margin:12px 0 0;padding:15px 17px;
  background:var(--neutral-950);
  border:1px solid var(--border-hairline);
  border-radius:var(--radius);
}
.widget .ct-cite .wm-labelrow{margin-bottom:4px}
.widget .ct-cite-text{width:100%;box-sizing:border-box;margin:6px 0 10px}
.widget .ct-cite .inline{margin:0}
.widget .ct-cite .actions{margin:10px 0 0}
.widget .ct-cite p.wm-hint{margin:0 0 8px}

.widget input.ct-locked{
  color:var(--tint-lime);font-weight:600;
  border-color:color-mix(in srgb,var(--tint-lime) 45%,transparent);
  background:color-mix(in srgb,var(--tint-lime) 7%,transparent);
  -moz-appearance:textfield;           /* no spinner on a count nobody may type */
}
.widget input.ct-locked::-webkit-inner-spin-button,
.widget input.ct-locked::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}

.widget .ct-cite-out{
  margin:12px 0 0;padding:12px 14px;
  border:1px solid var(--border-hairline);border-radius:var(--radius-sm);
  font-size:1rem;line-height:1.6;color:var(--ink);
}
.widget .ct-cite-out.ok{border-color:color-mix(in srgb,var(--tint-lime) 55%,transparent)}
.widget .ct-cite-out.warn{border-color:color-mix(in srgb,var(--tint-ice) 55%,transparent)}
.widget .ct-cite-out.bad{border-color:color-mix(in srgb,var(--tint-ember) 55%,transparent)}
.widget .ct-cite-out p{margin:0 0 8px;color:var(--ink)}
.widget .ct-cite-out p:last-child{margin-bottom:0}
.widget .ct-cite-out strong{color:var(--ink)}

.widget .ct-cite-list{list-style:none;margin:10px 0;padding:0}
.widget .ct-cite-row{
  display:flex;gap:12px;align-items:baseline;flex-wrap:wrap;
  padding:8px 0 8px 11px;margin:0 0 2px;
  border-left:3px solid var(--border-hairline);
  border-bottom:1px dashed var(--border-hairline);
  font-size:1.02rem;line-height:1.5;
}
.widget .ct-cite-row:last-child{border-bottom:0}
.widget .ct-cite-row.ok{border-left-color:var(--tint-lime)}
.widget .ct-cite-row.warn{border-left-color:var(--tint-ice)}
.widget .ct-cite-row.bad{border-left-color:var(--tint-ember)}
.widget .ct-cite-cite{font-family:var(--font-mono);font-size:.98rem;color:var(--ink);flex:0 0 auto}
.widget .ct-cite-verdict{
  flex:0 0 auto;font-size:.95rem;letter-spacing:.05em;text-transform:uppercase;
}
.widget .ct-cite-row.ok .ct-cite-verdict{color:var(--tint-lime)}
.widget .ct-cite-row.warn .ct-cite-verdict{color:var(--tint-ice)}
.widget .ct-cite-row.bad .ct-cite-verdict{color:var(--tint-ember)}
.widget .ct-cite-detail{flex:1 1 220px;color:var(--fg-muted);font-size:.98rem}
.widget .ct-cite-case{color:var(--brand-200)}
.widget .ct-cite-when,.widget .ct-cite-court{color:var(--fg-muted)}
.widget .ct-cite-note{color:var(--fg-muted)}
.widget .ct-cite-digest{font-family:var(--font-mono);font-size:.95rem;color:var(--brand-200)}

@media (max-width:560px){
  .widget .ct-cite-row{flex-direction:column;gap:2px}
  .widget .ct-cite-detail{flex:1 1 auto}
}

@media print{
  .widget .ct-cite{display:none}
}


/* =========================================================================
   .nt-settle / .nt-pay  —  x402, settled (notarize demo, app/notarize.js)
   -------------------------------------------------------------------------
   The 402 used to be the end of the road: a price was quoted and nothing on
   either side could act on it. These are the controls that close the loop.
     - the terms are a box of their own, because a price is not an error and
       should not be read as one. It is an amber edge, not a red one
     - the address and the amount each get their own copy button. An address
       retyped by hand is money sent to an address that does not exist, and
       that is the single most expensive mistake available on this page
     - the value sits in a <code> at full width and wraps: a truncated
       address with an ellipsis in it is not something anyone can check
     - settled is a lime edge and says what settled, not "success"
     - a refusal repeats the server's own words. An underpayment, a replay
       and a Blockfrost outage are three different problems
   ========================================================================= */

.widget .nt-settle{
  margin:14px 0 0;padding:15px 17px;
  background:var(--neutral-950);
  border:1px solid var(--border-hairline);
  border-radius:var(--radius);
}
.widget .nt-settle .actions{margin:10px 0 0}
.widget .nt-settle p.wm-hint{margin:0 0 10px}

.widget .nt-pay{
  margin:12px 0 0;padding:14px 16px;
  border:1px solid color-mix(in srgb,var(--tint-ice) 55%,transparent);
  border-radius:var(--radius-sm);
  background:color-mix(in srgb,var(--tint-ice) 6%,transparent);
}
.widget .nt-pay h3{color:var(--tint-ice);margin-bottom:8px}
.widget .nt-pay-lede{margin:0 0 12px;color:var(--ink);font-size:1rem;line-height:1.6}

.widget .nt-pay-line{
  display:flex;gap:10px;align-items:center;flex-wrap:wrap;
  padding:9px 0;border-bottom:1px dashed var(--border-hairline);
}
.widget .nt-pay-line:last-of-type{border-bottom:0}
.widget .nt-pay-k{
  flex:0 0 130px;font-size:.88rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--fg-muted);
}
.widget .nt-pay-v{
  flex:1 1 300px;min-width:0;
  font-family:var(--font-mono);font-size:.95rem;color:var(--ink);
  word-break:break-all;line-height:1.5;
}
.widget .nt-copy{flex:0 0 auto;padding:6px 12px;font-size:.9rem}
.widget .nt-copy.copied{border-color:var(--tint-lime);color:var(--tint-lime)}
.widget .nt-pay-sub{margin:10px 0 0;font-size:.98rem;line-height:1.6}
.widget .nt-pay-sub .chip{margin:0 6px 0 0}
.widget .nt-pay-tx{margin:12px 0 0}
.widget .nt-pay-tx input{width:100%;box-sizing:border-box}

.widget .nt-settled{
  margin:12px 0 0;padding:13px 15px;
  border:1px solid color-mix(in srgb,var(--tint-lime) 55%,transparent);
  border-radius:var(--radius-sm);
}
.widget .nt-settled p{color:var(--ink)}
.widget .nt-settled .mark{color:var(--tint-lime);font-weight:600}
.widget .nt-settled strong{color:var(--tint-lime)}

.widget .nt-pay-bad{
  margin:12px 0 0;padding:13px 15px;
  border:1px solid color-mix(in srgb,var(--tint-ember) 55%,transparent);
  border-radius:var(--radius-sm);
}
.widget .nt-pay-bad p{color:var(--ink)}
.widget .nt-pay-bad strong{color:var(--tint-ember)}

@media (max-width:560px){
  .widget .nt-pay-k{flex:1 1 100%}
  .widget .nt-copy{width:100%}
}

/* Workplace compose bar: the thread is the page, the box sits under it. */
.wp-compose{margin-top:14px}
.wp-composebar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;margin-top:10px}
.wp-composeleft{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.wp-file{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.wp-attach{cursor:pointer}
.wp-pick{display:inline-flex;align-items:center;gap:7px;font-size:.86rem;color:var(--fg-muted)}
.widget .wp-pick .wp-select{
  background:var(--chip-bg);color:var(--ink);border:1px solid var(--border-hairline);
  border-radius:999px;padding:8px 12px;font-family:var(--font-body);font-size:.9rem;
  appearance:none;-webkit-appearance:none;
}
.widget .wp-pick .wp-select:hover{border-color:var(--accent-ring)}
.wp-thread{min-height:340px}

/* Foldable sections: the notarize tool and the API log are options, not the main event. */
.wp-fold{margin-top:14px;border:1px solid var(--border-hairline);border-radius:var(--radius-lg);
  background:color-mix(in srgb,var(--neutral-900) 55%,transparent);padding:0 16px}
.wp-fold > summary{
  cursor:pointer;list-style:none;padding:14px 0;font-weight:500;color:var(--ink);
  display:flex;align-items:center;gap:10px;
}
.wp-fold > summary::-webkit-details-marker{display:none}
.wp-fold > summary::before{content:'\25B8';color:var(--fg-muted);transition:transform .15s ease}
.wp-fold[open] > summary::before{transform:rotate(90deg)}
.wp-fold > summary:hover{color:var(--accent)}
.wp-fold > *:last-child{margin-bottom:14px}
.wp-fold .widget{border:0;background:none;padding:0}
