.console-shell{display:grid;grid-template-columns:minmax(260px,360px) 1fr;min-height:calc(100vh - 76px)}.task-pane,.detail-pane{padding:clamp(1rem,4vw,3rem)}.task-pane{border-right:var(--line);background:#fff}.console-heading,.detail-head{display:flex;justify-content:space-between;gap:1rem;align-items:flex-start}.console h1,.console h2{margin:.3rem 0 1.5rem;line-height:.95;letter-spacing:-.06em}.console h1{font-size:clamp(3rem,7vw,5rem)}.console h2{font-size:clamp(1.8rem,4vw,3rem);max-width:700px}.task-list{display:grid;gap:.8rem;margin-top:2rem}.task-card{display:grid;gap:.3rem;text-align:left;background:var(--paper);border:var(--line);padding:1rem;box-shadow:3px 3px 0 var(--ink)}.task-card.selected{background:var(--lime)}.task-card span,.artifact span,.event-panel small{font-size:.78rem;font-weight:700;text-transform:uppercase}.console form{display:grid;gap:1rem;border:var(--line);padding:1rem;margin-top:1rem}.console label{display:grid;gap:.35rem;font-weight:900}.console textarea,.console select{font:inherit;padding:.7rem;border:var(--line);background:white}.detail-pane{background:var(--blue);min-width:0}.detail-head,.event-panel,.artifact-panel{background:var(--paper);border:var(--line);padding:1.2rem;box-shadow:var(--shadow);margin-bottom:1.2rem}.event-panel ol{list-style:none;padding:0;margin:0}.event-panel li{display:grid;gap:.15rem;padding:.8rem 0;border-bottom:1px dashed #777}.status{display:inline-block;border:var(--line);padding:.25rem .5rem;font-weight:900;text-transform:uppercase;background:var(--lime)}.status-failed{background:var(--red)}.danger{background:var(--red)}.artifact{display:flex;justify-content:space-between;gap:1rem;border-top:1px solid #999;padding:.8rem 0}.empty-state{background:var(--paper);border:var(--line);padding:2rem;font-weight:900}.muted{opacity:.65}.console-lock{font-size:.8rem;font-weight:900;text-transform:uppercase}@media(max-width:760px){.console-shell{display:block}.task-pane{border-right:0;border-bottom:var(--line)}.detail-pane{min-height:70vh}.artifact{display:grid}.detail-head{display:grid}.console .button{width:100%}}
.auth-pane{width:min(560px,calc(100% - 2rem));margin:3rem auto;padding:clamp(1.5rem,5vw,4rem);background:var(--paper);border:var(--line);box-shadow:var(--shadow)}.auth-pane h1{font-size:clamp(3rem,8vw,6rem);margin:.3rem 0 1rem}.auth-pane input{font:inherit;padding:.7rem;border:var(--line);display:block;width:100%;margin-top:.35rem}.auth-pane form{display:grid;gap:1rem;margin-top:1.5rem}.app-view{display:contents}

/* Defensive: a generic display rule (e.g. ".console form{display:grid}") on the same element
   as the plain `hidden` attribute silently wins over it per the CSS cascade (author-normal
   always outranks UA-normal, regardless of specificity -- see MDN's hidden-attribute caveat).
   styles.css already uses !important for its own .hidden CLASS for the same reason; this
   extends the same convention to the ATTRIBUTE form, which #task-form/#totp-form already rely
   on and the new redeem/paste/feedback toggles below also use. */
[hidden]{display:none!important}
/* S1/S2: persistent credit balance + get-connected row above the task/detail grid. */
.top-row{grid-column:1/-1;display:grid;grid-template-columns:minmax(280px,380px) 1fr;gap:1rem;padding:clamp(1rem,4vw,3rem) clamp(1rem,4vw,3rem) 0}
.balance-card,.connect-row{background:var(--paper);border:var(--line);box-shadow:var(--shadow);padding:1.2rem}
.balance-card .number{margin:.2rem 0;letter-spacing:-.04em}
.balance-explainer{font-size:.92rem;margin:.4rem 0 1rem}
.balance-actions{display:flex;gap:.7rem;flex-wrap:wrap}
.balance-card form{margin-top:1rem}
.link-button{background:none;border:0;text-decoration:underline;font-weight:900;cursor:pointer;padding:0;margin-top:.8rem;display:block;font:inherit}
.connect-tiles{display:grid;grid-template-columns:repeat(2,1fr);gap:.7rem;margin-top:.8rem}
.connect-tile{display:grid;gap:.2rem;text-align:left;background:white;border:var(--line);padding:.8rem;box-shadow:3px 3px 0 var(--ink);text-decoration:none;color:inherit;font:inherit;cursor:pointer;transition:.15s transform,.15s box-shadow}
.connect-tile:hover{transform:translate(2px,2px);box-shadow:1px 1px 0 var(--ink)}
.connect-tile strong{font-size:.95rem}
.connect-tile span{font-size:.78rem;font-weight:700;opacity:.75}

/* P11: lane picker (real, allowlisted lanes -- codex-par / ainur-do). */
.lane-picker{border:0;padding:0;margin:0;display:flex;gap:.8rem;flex-wrap:wrap}
.lane-picker legend{font-weight:900;padding:0 0 .35rem}
.lane-card{display:grid;gap:.15rem;border:var(--line);background:white;padding:.7rem 1rem;cursor:pointer;min-width:160px}
.lane-card input{position:absolute;opacity:0;pointer-events:none}
.lane-card.selected{background:var(--lime)}
.lane-name{font-weight:900}
.lane-tier{font-size:.78rem;font-weight:700;text-transform:uppercase;opacity:.75}

/* P10: inline thumbs-up/down + optional tag chips on a task's result. */
.feedback-panel{background:var(--paper);border:var(--line);box-shadow:var(--shadow);padding:1.2rem;margin-bottom:1.2rem}
.feedback-thumbs{display:flex;gap:.6rem;margin-top:.4rem}
.thumb{border:var(--line);background:white;padding:.5rem 1rem;font-weight:900}
.thumb.selected{background:var(--lime)}
.feedback-tags{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.9rem}
.chip{border:var(--line);background:white;padding:.35rem .7rem;font-weight:900;font-size:.78rem;text-transform:uppercase;cursor:pointer}
.chip.selected{background:var(--lime)}
.chip.dismiss{background:var(--red)}
.feedback-sent{margin-top:.7rem;font-weight:900}

/* S1: MCP client picker -- reuses the site-wide .codebox/.copy convention from styles.css
   (same visual language as docs.html's tabbed setup snippets) instead of inventing a new one. */
.connect-picker{margin-bottom:1rem}
.connect-picker select{font:inherit;padding:.6rem;border:var(--line);background:white;width:100%;margin-top:.3rem}
.connect-picker .codebox{margin-top:.7rem}
.connect-picker .hint{font-size:.75rem;opacity:.7;margin-top:.5rem}

/* S5: key hygiene -- session token (no spend power) and the billing API key (secret, spends
   credits) get visually separated cards so the risk difference is legible, not just documented. */
.key-hygiene{display:grid;gap:.7rem;margin-top:1.1rem}
.key-card{border:var(--line);background:white;padding:.8rem .9rem}
.key-card-head{display:flex;justify-content:space-between;align-items:center;gap:.6rem;flex-wrap:wrap}
.key-card-head strong{font-size:.92rem}
.key-risk{font-size:.68rem;font-weight:900;text-transform:uppercase;padding:.2rem .45rem;border:var(--line);white-space:nowrap}
.key-risk.ok{background:var(--lime)}
.key-risk.danger{background:var(--red)}
.key-card-copy{font-size:.8rem;margin:.5rem 0;opacity:.85}
.key-card .key-row{margin:.4rem 0 0}
.key-card .key-row code{font-size:.8rem}

/* P3: collapsible reasoning trace above the event/result panel -- collapsed by default so a
   long pipeline does not push the result out of view, but every line shown is a real event. */
.steps-toggle{display:flex;align-items:center;gap:.4rem;background:none;border:0;padding:0;margin:0 0 .8rem;font:inherit;font-weight:900;cursor:pointer;text-align:left;color:inherit}
.steps-toggle .chev{display:inline-block;transition:transform .15s}
.steps-toggle[aria-expanded="true"] .chev{transform:rotate(90deg)}

/* P14: honest in-progress copy (real elapsed time + latest live event) instead of a bare status
   badge with no sense of whether anything is actually happening. */
.progress-honesty{background:var(--paper);border:var(--line);box-shadow:var(--shadow);padding:1rem 1.2rem;margin-bottom:1.2rem}
.progress-honesty p{margin:.2rem 0;font-weight:700}
.progress-honesty .muted{font-weight:500}

@media(max-width:760px){.top-row{grid-template-columns:1fr}.connect-tiles{grid-template-columns:1fr}}
