/* Faber XTOCAD — the whole look of the product.
 *
 * THREE RULES.
 *
 * 1. THE MODEL IS THE SURFACE. In a project the geometry is full bleed and
 *    every control sits at an edge of it. Nothing floats in the middle but
 *    the agent's own voice and, when it has one, its question.
 *
 * 2. THE PALETTE IS THE SITE'S, value for value: the constellation void
 *    (#060608), its panel (#0d0d11) and hair rule, parchment ink, and the
 *    one acid #d8ef62 that marks live state and whatever you press. Read out
 *    of faber-website/app/constellation.css and fabulous/ui/static/app.css.
 *
 * 3. SOBER, AND SOFTLY CORNERED. The site rounds nothing; this product
 *    rounds 6-10px and nothing more. Jules's call: "un peu moins carré".
 *    Type: Instrument Sans (the site's), Newsreader italic for the agent's
 *    voice and one emphasised line, Geist Mono for every micro label and
 *    number. All three are served from /static/fonts — this product makes
 *    no network request of its own.
 */

@font-face{font-family:Instrument Sans;src:url('/static/fonts/instrument-sans-400-600-latin.woff2') format('woff2');font-weight:400 600;font-style:normal;font-display:swap}
@font-face{font-family:Geist Mono;src:url('/static/fonts/geist-mono-latin.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:Newsreader;src:url('/static/fonts/newsreader-italic-300-latin.woff2') format('woff2');font-style:italic;font-weight:300;font-display:swap}

:root{
  --void:#060608;
  --panel:#0d0d11;
  --hair:rgba(226,216,192,.10);
  --hair-strong:rgba(226,216,192,.16);
  --ink:#f3ebdb;
  --ink-2:#dcd7c9;
  --ink-soft:#8f948c;
  --ink-mute:rgba(222,213,194,.38);
  --acid:#d8ef62;
  --on-acid:#17332c;
  --warm:#efaa98;
  --radius:9px;
  --radius-sm:6px;
  --sans:"Instrument Sans",Arial,Helvetica,sans-serif;
  --mono:"Geist Mono",ui-monospace,Consolas,monospace;
  --serif:Newsreader,Georgia,serif;
  color-scheme:dark;
  font-family:var(--sans);
  color:var(--ink);
  background:var(--void);
}

*{box-sizing:border-box}
html{min-height:100%}
body{margin:0;background:transparent;overflow-y:auto;user-select:text;-webkit-font-smoothing:antialiased}
body.in-project{overflow:hidden}
button,a,textarea,input{font:inherit}
button{color:inherit;cursor:pointer;border:0;background:transparent;padding:0}
button:disabled{opacity:.5;cursor:wait}
a{color:inherit;text-decoration:none}
button,a,input,textarea{outline-offset:3px}
button:focus-visible,a:focus-visible{outline:2px solid var(--acid)}
/* A text field never wears the acid ring: the panel around it carries the
   focus, so writing does not put a yellow rectangle on the page. */
textarea:focus,textarea:focus-visible,input:focus,input:focus-visible{outline:none}
dialog textarea:focus,#project-name:focus{border-color:rgba(226,216,192,.45)}
[hidden]{display:none!important}
h1,h2,h3,p{margin:0}
svg{flex-shrink:0}
::selection{background:rgba(240,228,200,.25)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}

.micro{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-mute)}
.num{font-family:var(--mono);font-size:11px;letter-spacing:.04em;color:#7e837b}
.eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-mute)}
.tag{font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:#8b9089;border:1px solid rgba(226,216,192,.13);border-radius:4px;padding:5px 7px}
/* THE ONE PICTURE OF WORKING: the mark drawn by a compass, Fabulous's own
   file, animating inside its own document. It is an <img>, so the browser
   fetches and caches it once however many rows are building at the time, and
   the file carries its own reduced-motion branch. */
.compass{display:block;flex-shrink:0;width:18px;height:18px}
.dot{width:5px;height:5px;border-radius:50%;background:#737d75;display:block;flex-shrink:0}
.dot.running,.dot.queued,.dot.stopping,.dot.awaiting_answer,.dot.in_studio{background:var(--acid)}
.dot.running{animation:breathe 2.4s infinite}
.dot.error,.dot.interrupted{background:var(--warm)}

/* One quiet field. Faint nebulae, a few stars, nothing that competes. */
.sky{pointer-events:none;position:fixed;inset:0;z-index:-1;background:radial-gradient(ellipse 1100px 620px at 50% 22%,rgba(114,122,148,.10),transparent 72%),var(--void)}
.sky:after{content:'';position:absolute;inset:0;opacity:.35;background-image:radial-gradient(1px 1px at 60px 90px,rgba(243,235,219,.5),transparent),radial-gradient(1px 1px at 300px 240px,rgba(243,235,219,.3),transparent),radial-gradient(1px 1px at 180px 380px,rgba(243,235,219,.22),transparent);background-size:520px 460px}

/* ------------------------------------------------------------------ chrome */
header{position:relative;z-index:8;height:78px;display:flex;align-items:center;gap:14px;padding:0 40px}
body.in-project header{border-bottom:1px solid var(--hair)}
.wordmark{display:flex;align-items:center;gap:11px;color:#ded5c2;margin-right:12px}
.wordmark svg{width:23px;height:23px}
.wordmark span{font-size:13px;letter-spacing:.42em;font-weight:500}
/* THE WAY TO EVERYTHING ELSE: a word and a count at the far right, not a box.
   In a project the same button takes the left, says where it goes, and drops
   the count — which is only ever refreshed off the home page. */
.pill{margin-left:auto;display:flex;align-items:baseline;gap:9px;font-size:12.5px;color:var(--ink-soft)}
.pill .num{font-size:11px;color:var(--ink-mute)}
.pill:hover{color:var(--ink-2)}
body.on-projects .pill{color:var(--ink-2)}
body.in-project .pill{margin-left:0;padding:8px 4px}
body.in-project .pill .num{display:none}


/* THE AGENT'S LINE, ONCE THERE IS SOMETHING TO LOOK AT. Before the first
   build it is the big italic sentence over the empty stage; after it the same
   words come up here, small and out of the model's way — Fabulous's move when
   its first version lands. It is the only thing in the bar that may grow, so
   it takes the slack and clips rather than shoving the run state off the end. */
#head-thought{flex:1 1 auto;min-width:0;margin:0 6px;font-family:var(--serif);font-style:italic;font-weight:300;font-size:14px;line-height:1.35;color:#8d968b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body:not(.in-project) #head-thought{display:none}
#head-thought.streaming:after{content:'';display:inline-block;width:6px;height:11px;margin-left:5px;vertical-align:-1px;background:var(--acid);opacity:.8;animation:blink 1.1s steps(1) infinite}

/* One press to start something else, and only where there is something else
   going on: on home the entry IS the page, and the list has its own word. */
.icon-button{display:none;place-items:center;width:28px;height:28px;margin-left:-2px;border-radius:6px;color:var(--ink-soft);border:1px solid transparent;transition:color .15s ease,border-color .15s ease,background-color .15s ease,transform .15s ease}
.icon-button svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2}
.icon-button:hover{color:var(--ink);border-color:var(--hair-strong);background:rgba(226,216,192,.05)}
.icon-button:active{transform:scale(.9)}
body.in-project .icon-button{display:grid}
/* The account is not a project's business, so its mark stands at the far end of
   the bar on every page, including the ones a project never opens. */
#account-button{display:grid;margin-left:auto}
body.in-project #account-button{margin-left:16px}

.chrome-right{display:flex;align-items:center;gap:16px}
.run-state{display:none;align-items:center;gap:8px;font-size:12px;color:#c3c9bb;white-space:nowrap}
body.in-project .run-state{display:flex}
.ghost{font-size:11.5px;color:#c6c9bf;border:1px solid var(--hair-strong);padding:7px 12px;border-radius:var(--radius-sm);white-space:nowrap}
.ghost:hover{color:var(--ink);border-color:rgba(226,216,192,.3)}
body:not(.in-project) .chrome-right{display:none}
/* HOW LONG THIS RUN HAS BEEN GOING, and nothing more: progress comes from the
   plan and never from a clock. Blank rather than 00:00 when there is no run —
   no number is better than a wrong one. */
#run-elapsed{font-size:11px;letter-spacing:.18em;color:#7e837b;font-variant-numeric:tabular-nums}
#run-elapsed:empty{display:none}

/* -------------------------------------------------------------------- home */
/* ONE QUESTION AND THE LINE YOU ANSWER IT ON. The entry sits in the middle of
   the band that is free — under the header, above whatever is alive — so it
   never reads as a panel pushed down by a margin. The field grows with the
   text and the only graphic is the acid rule under the whole row. */
#home{position:relative;z-index:1;min-height:calc(100vh - 78px);display:flex;flex-direction:column}
.entry{flex:1 0 auto;display:flex;align-items:center;justify-content:center;padding:36px 24px}
.entry-block{width:880px;max-width:100%}
.entry h1{text-align:center;font-family:var(--serif);font-style:italic;font-weight:300;font-size:38px;line-height:1.3;letter-spacing:-.012em;color:var(--ink-2)}
/* SHUT IT IS A LINE, OPEN IT IS A ROOM, and it is the same box either way.
   Shut: one narrow rule with the sentence on it and the one button that starts
   a build. Click it and the acid rule climbs the sides into a rectangle while
   the box widens and deepens on a single ease, the lime flaring once as it
   arrives and the tools coming up underneath. */
.composer{position:relative;width:min(680px,100%);margin:52px auto 0;padding:0;border:1px solid transparent;border-bottom-color:rgba(216,239,98,.5);border-radius:0;background:transparent;cursor:text;transition:width .36s cubic-bezier(.2,.75,.2,1),padding .36s cubic-bezier(.2,.75,.2,1),border-color .3s ease,border-radius .28s ease,background-color .36s ease}
.composer:hover{border-bottom-color:rgba(216,239,98,.78)}
.composer.is-open{width:100%;padding:18px 12px 12px 20px;border-color:rgba(216,239,98,.34);border-radius:12px;background:rgba(11,11,15,.7);animation:entry-flare .62s ease-out}
.composer.is-open:focus-within{border-color:rgba(216,239,98,.56)}
/* The lime is not just where the box ends up — it is in the move itself. */
@keyframes entry-flare{from{box-shadow:0 0 0 0 rgba(216,239,98,.34),0 0 26px rgba(216,239,98,.2)}to{box-shadow:0 0 0 18px rgba(216,239,98,0),0 0 26px rgba(216,239,98,0)}}
/* Shut, the bar carries the sentence and the build and nothing else. */
.composer:not(.is-open) .clip,.composer:not(.is-open) .flag,.composer:not(.is-open) .mode-switch{display:none}
.composer.is-open .clip,.composer.is-open .flag,.composer.is-open .mode-switch{animation:tool-in .3s .06s cubic-bezier(.2,.75,.2,1) backwards}
@keyframes tool-in{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
textarea{width:100%;resize:none;border:0;background:transparent;color:var(--ink);line-height:1.6;outline:none}
textarea::placeholder{color:#767a72}
.composer textarea{flex-grow:1;min-width:0;font-size:16px;line-height:1.5;field-sizing:content;max-height:38vh;transition:font-size .3s cubic-bezier(.2,.75,.2,1)}
.composer.is-open textarea{font-size:19px;min-height:62px}
.composer textarea::placeholder{color:#5f6560}
.composer-bottom{display:flex;align-items:flex-end;gap:28px;padding-bottom:14px}
.entry-tools{display:flex;align-items:center;gap:6px;flex-shrink:0;padding-bottom:3px}
/* Open, the text takes the top of the box and the tools sit under it on the same
   surface: attach and the two flags on the left, the model and Build on the right. */
.composer.is-open .composer-bottom{flex-direction:column;align-items:stretch;gap:20px;padding-bottom:0}
.composer.is-open .entry-tools{margin-left:-8px;padding-bottom:0}
/* Attaching is one gesture, so it is one button: a clip with a hit area and no
   word. Ghost until you are over it. */
.clip{display:grid;place-items:center;width:34px;height:34px;border-radius:7px;color:var(--ink-soft);border:1px solid transparent;transition:color .15s,border-color .15s,background-color .15s}
.clip svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9}
.composer .clip{border-radius:8px;color:var(--ink-2)}
.composer .clip svg{width:18px;height:18px;stroke-width:1.8}
.clip:hover{color:var(--ink-2);border-color:var(--hair-strong);background:rgba(226,216,192,.04)}
.subtle{display:flex;align-items:center;gap:7px;font-size:12.5px;color:#a8ada4;padding:6px 6px 6px 0;border-radius:var(--radius-sm)}
.subtle:hover{color:var(--ink)}
.subtle svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7}
/* A FLAG, NOT A SEGMENT: Creative and Concept first each say on or off about one
   idea, quiet until they are on, and then they wear the acid as an outline —
   the solid acid on this row belongs to Build. */
.flag{display:flex;align-items:center;gap:7px;padding:7px 11px;border-radius:8px;border:1px solid transparent;font-size:12.5px;color:var(--ink-soft);transition:color .15s,border-color .15s,background-color .15s}
.flag svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7}
.flag:hover{color:var(--ink-2)}
.flag[aria-pressed=true]{color:var(--acid);border-color:rgba(216,239,98,.30);background:rgba(216,239,98,.08)}
/* Concept first changes what happens first, so while the box is open it says
   what that is, once, under the box. */
#concept-hint{display:flex;align-items:flex-start;gap:9px;margin-top:14px;padding:0 20px;font-size:12.5px;line-height:1.5;color:var(--ink-soft)}
#concept-hint svg{width:14px;height:14px;margin-top:2px;fill:none;stroke:var(--acid);stroke-width:1.7}
.composer:not(.is-open)+#concept-hint{display:none}
/* The two models are one chip with two halves; the one in use is lit. */
.mode-switch{margin-left:auto;display:flex;align-items:center;gap:2px;padding:3px;border-radius:9px;background:rgba(226,216,192,.05)}
.mode-switch button{padding:6px 12px;border-radius:6px;font-size:12.5px;color:var(--ink-soft);transition:color .2s ease,background-color .2s ease,transform .12s ease}
.mode-switch button:hover{color:var(--ink-2)}
.mode-switch button[aria-pressed=true]{background:rgba(226,216,192,.10);color:var(--ink)}
.mode-switch button:active{transform:scale(.92)}
.mode-switch button.picked{animation:mode-pop .36s cubic-bezier(.2,.75,.2,1)}
@keyframes mode-pop{0%{transform:scale(.9)}45%{transform:scale(1.1)}100%{transform:none}}
.model-picker{position:relative;margin-left:6px}
.model-picker>button{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:7px;font-size:12.5px;color:var(--ink);background:rgba(226,216,192,.05);transition:background-color .2s ease}
.model-picker>button:hover{background:rgba(226,216,192,.10)}
.model-picker>button svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.2;transition:transform .18s ease}
.model-picker>button[aria-expanded=true] svg{transform:rotate(180deg)}
.model-menu{position:absolute;right:0;bottom:calc(100% + 6px);z-index:20;min-width:180px;padding:4px;border:1px solid rgba(226,216,192,.14);border-radius:9px;background:#14170f;box-shadow:0 18px 40px rgba(0,0,0,.55)}
.model-menu button{display:block;width:100%;text-align:left;padding:8px 10px;border-radius:6px;font-size:12.5px;color:var(--ink-soft)}
.model-menu button:hover{background:rgba(226,216,192,.08);color:var(--ink)}
.model-menu button[aria-selected=true]{color:var(--acid)}
.model-menu p{padding:8px 10px;font-size:12px;color:var(--ink-soft)}
#account-dialog h2{margin-bottom:2px}
.account-email{font-size:12.5px;color:var(--ink-soft)}
.connection{margin-top:20px;padding:15px;border:1px solid var(--hair-strong);border-radius:9px}
/* The mark, the name and the state are one row: the card holds one connection,
   and a reader takes in whose it is and whether it is live in a single glance.
   The state shares the title's baseline rather than the block's centre, which
   would leave it floating between two lines and aligned with neither. */
.connection-head{display:flex;align-items:center;gap:14px}
/* Dialog images are full-width illustrations with a margin under them; this one
   is a mark on a row, so it takes none of that. */
.connection-head img{width:44px;height:44px;flex:none;margin:0;border-radius:0}
.connection-text{flex:1;min-width:0}
.connection-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px}
.connection-title{font-size:13.5px;color:var(--ink)}
.connection-sub{margin-top:4px;font-size:11.5px;color:var(--ink-mute)}
.connection-state{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink-soft);white-space:nowrap}
.connection-state::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ink-mute)}
.connection.connected .connection-state{color:var(--ink)}
.connection.connected .connection-state::before{background:var(--acid)}
.connection-body{margin-top:15px;padding-top:15px;border-top:1px solid rgba(226,216,192,.10);font-size:12.5px;line-height:1.55;color:var(--ink-soft)}
/* The pairing happens in two windows, so the panel counts the steps out loud.
   The number comes from the list rather than from a span in each row: what the
   reader counts and what the markup counts cannot then drift apart. */
.pairing-steps{list-style:none;margin:0;padding:0;counter-reset:pairing}
.pairing-steps>li{position:relative;padding:0 0 15px 30px;counter-increment:pairing}
.pairing-steps>li:last-child{padding-bottom:0}
.pairing-steps>li::before{content:counter(pairing);position:absolute;left:0;top:0;width:19px;height:19px;border-radius:50%;border:1px solid rgba(226,216,192,.22);font-family:var(--mono);font-size:10.5px;line-height:18px;text-align:center;color:var(--ink-2)}
.pairing-steps b{font-weight:500;color:var(--ink-2)}
/* The code and the way to take it are ONE object: a code a person can read but
   not copy is a code they mistype once and give up on. */
.pairing-code{display:flex;align-items:center;gap:12px;margin:9px 0 0}
.connection-body strong{font-family:var(--mono);font-size:22px;font-weight:500;letter-spacing:.16em;color:var(--acid)}
a.pairing-open{display:inline-block;margin-top:9px;text-decoration:none}
/* The prerequisite reads as part of the card and ABOVE the code, because it is
   something to do before pressing rather than a footnote under a code that is
   already ticking. Its own rule, so it does not read as a caption to the line
   above it. */
.connection-hint{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;margin-top:15px;padding-top:15px;border-top:1px solid rgba(226,216,192,.10);font-size:11.5px;line-height:1.55;color:var(--ink-mute)}
.connection-hint b{font-weight:500;color:var(--ink-2)}
.connection-hint a{color:var(--ink-soft);white-space:nowrap}
.connection-hint a:hover{color:var(--acid)}
.account-note{margin-top:10px;font-size:11.5px;color:var(--ink-mute)}
.connection-actions{display:flex;gap:10px;margin-top:15px}
.connection-actions:has(button[hidden]:only-child),.connection-actions:not(:has(button:not([hidden]))){display:none}
.composer #create-button{margin-left:6px;border-radius:8px}
.primary{display:inline-flex;align-items:center;justify-content:center;gap:12px;background:var(--acid);color:var(--on-acid);font-size:12.5px;font-weight:600;border-radius:7px;padding:11px 16px;transition:background .15s}
.primary:hover{background:#e5f5a8}
.primary svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.4}
.primary.light{background:#e8e5dc;color:#242621;padding:12px 17px}
.primary.light:hover{background:#fffdf7}
.drop-message{display:none;position:absolute;inset:0;background:rgba(11,13,10,.96);border:1px dashed var(--acid);border-radius:var(--radius);align-items:center;justify-content:center;color:var(--acid);font-size:15px}
.dragover .drop-message{display:flex}
.file-chips{display:flex;flex-wrap:wrap;gap:7px}
.file-chips:not(:empty){margin-bottom:10px}
.chip{display:flex;align-items:center;gap:9px;padding:7px 10px;border:1px solid rgba(226,216,192,.14);border-radius:var(--radius-sm);font-size:11.5px;color:#cfc9ba;max-width:100%}
.chip span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:300px}
.chip button{color:#8b9089;padding:0 2px}
.chip button:hover{color:var(--ink)}

/* WHAT IS ALIVE, AND NOTHING ELSE: a state, a name and a time. The agent's
   line and its question belong on the project, not on a row you have to read
   from across the page. */
#active{width:880px;max-width:calc(100% - 48px);margin:0 auto;padding-bottom:64px}
.active-row{display:flex;align-items:center;gap:14px;width:100%;padding:14px 0;border-top:1px solid var(--hair);text-align:left}
.active-row .dot{width:6px;height:6px}
.active-row .compass{width:17px;height:17px;margin:-4px -5px -4px -6px}
.active-row .dot.unread{background:var(--acid)}
.active-row .name{flex-grow:1;min-width:0;font-size:13px;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.active-row .elapsed{flex-shrink:0;color:var(--ink-soft)}
.active-row:hover .name{color:var(--ink)}
.quiet{padding:26px 0;border-top:1px solid var(--hair);font-size:12.5px;color:var(--ink-soft);line-height:1.6}

footer{display:flex;justify-content:space-between;gap:20px;width:720px;max-width:calc(100% - 48px);margin:64px auto 0;padding-bottom:36px}

/* ------------------------------------------------------------ my projects */
/* ONE CARD PER ROW, EACH WASHED WITH ITS OWN PROJECT'S TONE. The eight tones
   are assembly-colors.js's, taken on the project id, so the list is coloured
   by its own geometry and a project keeps its colour for life. The wash is
   13%: enough to tell two cards apart across the room, never a background. */
#projects-page{position:relative;z-index:1;width:1160px;max-width:calc(100% - 48px);margin:0 auto;padding-top:52px}
.projects-heading{display:flex;align-items:baseline;gap:16px;padding-bottom:16px}
.projects-heading h1{font-size:26px;font-weight:400;letter-spacing:-.02em;color:#f6efdf}
.projects-heading .num{font-size:12px;color:var(--ink-mute)}
/* Plain words, not pills: the one you are on is lit, the rest are quiet, and
   the acid rule slides under whichever you press. */
.filters{margin-left:auto;display:flex;align-items:center;gap:18px;font-size:12.5px}
.filters button{position:relative;padding:0 0 6px;font-size:12.5px;color:var(--ink-soft)}
.filters button:after{content:'';position:absolute;left:0;right:0;bottom:0;height:1px;border-radius:1px;background:var(--acid);opacity:0;transform:scaleX(.15);transition:opacity .2s ease,transform .3s cubic-bezier(.2,.75,.2,1)}
.filters button:hover{color:var(--ink-2)}
.filters button[aria-pressed=true]{color:var(--ink-2)}
.filters button[aria-pressed=true]:after{opacity:1;transform:none}
.heading-rule{height:1px;background:linear-gradient(90deg,rgba(216,239,98,.55),rgba(216,239,98,.10) 62%,transparent)}
.project-list{display:flex;flex-direction:column;gap:20px;margin-top:30px}
.project-card{position:relative;display:flex;align-items:stretch;overflow:hidden;background:var(--panel);border:1px solid var(--hair);border-radius:10px;transition:border-color .18s ease,transform .18s cubic-bezier(.2,.75,.2,1)}
.project-card:hover{border-color:rgba(226,216,192,.22);transform:translateY(-2px)}
.project-card.is-archived{opacity:.6}
.project-card.is-picked{border-color:rgba(216,239,98,.34)}
.project-card.is-picked .wash{background:rgba(216,239,98,.05)!important}
.wash{position:absolute;inset:0;pointer-events:none}
/* The card IS the button. Everything readable sits over this, out of the
   pointer's way, so a click anywhere but the menu or the box opens the run. */
.project-card .project-open{position:absolute;inset:0;z-index:1}
/* The card clips, so the keyboard ring is drawn inside it rather than lost. */
.project-card .project-open:focus-visible{outline-offset:-3px}
.project-card .card-stage,.project-card .card-side{position:relative;z-index:2;pointer-events:none}
.project-card .card-stage{width:640px;flex-shrink:0;display:grid;place-items:center;padding:20px 0}
/* No plate, in either state: the preview PNG is a silhouette with nothing
   behind it, so the card's own tinted surface runs straight under the part,
   and the compass placeholder floats on it the same way before there is one. */
.project-card .thumb{width:560px;max-width:100%;height:262px;display:grid;overflow:hidden}
.project-card .thumb img{width:100%;height:100%;object-fit:contain;display:block}
.project-card .thumb .glyph{place-self:center;width:54px;height:54px;opacity:.55}
.project-card .card-side{flex-grow:1;min-width:0;display:flex;flex-direction:column;justify-content:center;padding:30px 34px 30px 10px}
.card-index{font-family:var(--mono);font-size:10px;letter-spacing:.28em;color:rgba(222,213,194,.30)}
.card-title{margin-top:14px;font-size:30px;line-height:1.16;letter-spacing:-.028em;color:#f6efdf}
.card-meta{display:flex;align-items:center;gap:12px;margin-top:20px}
.card-meta .compass{width:21px;height:21px;margin-right:-4px}
.project-card .thumb .compass{place-self:center;width:76px;height:76px}
/* Spoken only when it is not done. Acid while it is alive or unopened, warm
   when the run is the one waiting on you; a finished project shows nothing. */
.state-chip{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;padding:6px 11px;border-radius:var(--radius-sm);color:var(--warm);background:rgba(239,170,152,.13)}
.state-chip.live{color:var(--on-acid);background:var(--acid)}
.card-when{font-family:var(--mono);font-size:11px;color:var(--ink-mute)}
.card-when:empty{display:none}
/* The row menu stays out of the calm until the pointer or the keyboard is on
   the card, and never leaves the page while a menu is actually open. */
.card-menu{position:absolute;top:13px;right:14px;z-index:3;opacity:0;transition:opacity .15s ease}
.project-card:hover .card-menu,.project-card:focus-within .card-menu,.card-menu[open]{opacity:1}
.card-menu summary{display:grid;place-items:center;list-style:none;width:26px;height:24px;cursor:pointer;color:#8b9089;border-radius:5px;font-size:17px;line-height:1}
.card-menu summary::-webkit-details-marker{display:none}
.card-menu summary:hover{color:var(--ink);background:rgba(226,216,192,.07)}
.card-menu[open]>div{animation:menu-in .18s cubic-bezier(.2,.75,.2,1)}
@keyframes menu-in{from{opacity:0;transform:translateY(-5px) scale(.98)}to{opacity:1;transform:none}}
.card-menu>div{position:absolute;right:0;top:30px;transform-origin:100% 0;min-width:190px;background:#131317;border:1px solid var(--hair-strong);border-radius:var(--radius-sm);padding:5px;box-shadow:0 12px 30px rgba(0,0,0,.5);z-index:5}
.card-menu button{display:block;width:100%;padding:9px 10px;text-align:left;font-size:11.5px;border-radius:4px;color:var(--ink-2)}
.card-menu button:hover{background:rgba(226,216,192,.07);color:var(--ink)}
.card-menu[open]{z-index:6}
/* Selection mode. A bar over the list that says how many and how to leave,
   with the destructive action last. */
#selection-bar{display:flex;align-items:center;gap:12px;margin-bottom:8px;padding:9px 12px;border:1px solid var(--hair-strong);border-radius:var(--radius);background:rgba(226,216,192,.03)}
#selection-count{margin-right:auto}
#selection-archive{padding:8px 13px;font-size:11.5px}
#selection-bar button:disabled{cursor:default}
/* In selection mode the box takes the card's top-left corner, where the menu
   is not, and stands above the surface button so it can be ticked directly. */
.row-check{position:absolute;top:16px;left:18px;z-index:3;width:16px;height:16px;margin:0;accent-color:var(--acid);cursor:pointer}
.row-check:focus-visible{outline:2px solid var(--acid)}
/* Both confirmations name the projects they are about, and read the same way. */
#bulk-archive-dialog p,#delete-dialog p{font-size:12.5px;line-height:1.7;color:var(--ink-soft);margin-top:-4px}
#bulk-archive-names,#delete-dialog ul{list-style:none;max-height:150px;overflow:auto;margin:16px 0 0;padding:0;font-size:12px;color:var(--ink-2)}
#bulk-archive-names li,#delete-dialog li{padding:7px 0;border-top:1px solid var(--hair);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Permanent deletion, the one action that takes something away: warm, never
   acid, and always behind a rule so no pointer lands on it by momentum. */
.card-menu button.danger{margin-top:5px;padding:11px 10px 9px;border-top:1px solid var(--hair);border-radius:0 0 4px 4px;color:var(--warm)}
.card-menu button.danger:hover{background:rgba(239,170,152,.10);color:var(--warm)}
#selection-delete{padding:8px 13px;font-size:11.5px;color:var(--warm);border-color:rgba(239,170,152,.28)}
#selection-delete:hover:not(:disabled){color:var(--warm);border-color:rgba(239,170,152,.55);background:rgba(239,170,152,.08)}
.eyebrow.danger{color:var(--warm)}
#delete-dialog label{display:block;margin:20px 0 8px;font-size:11.5px;color:var(--ink-soft)}
#delete-dialog label b{font-family:var(--mono);font-weight:400;color:var(--ink-2)}
#delete-word{width:100%;padding:11px 12px;background:rgba(8,14,12,.5);border:1px solid rgba(226,216,192,.13);border-radius:7px;color:var(--ink);font-family:var(--mono);font-size:13px}
#delete-word:focus{border-color:rgba(239,170,152,.5)}
#delete-confirm{background:var(--warm);color:#2b1512;font-size:12.5px;font-weight:600;border-radius:7px;padding:11px 16px}
#delete-confirm:hover{background:#f6c2b3}
#delete-confirm:disabled{background:transparent;color:var(--ink-mute);border:1px solid var(--hair-strong);cursor:default}
.empty-projects{padding:80px 4px;text-align:center;color:var(--ink-soft);font-size:12.5px;line-height:1.7}
.empty-projects strong{display:block;color:var(--ink-2);font-size:17px;font-weight:400;margin-bottom:10px}
/* Restoring a session is real and has to stay reachable, but it is not what
   this page is about: it reads as one quiet line at the bottom of the list. */
#projects-page footer{width:auto;align-items:center;margin-top:34px;padding-top:22px;border-top:1px solid var(--hair)}
#restore-session{font-size:12px;padding:6px 0}
/* Narrow enough and the stage cannot sit beside the name, so it goes over it
   and the card keeps its proportions rather than crushing the preview. */
@media(max-width:760px){
  .project-card{flex-direction:column}
  .project-card .card-stage{width:100%;padding:16px 0 0}
  .project-card .thumb{width:100%;height:180px}
  .project-card .card-side{padding:20px 22px 24px}
  .card-title{font-size:23px}
  .filters{gap:13px;font-size:12px}
}

/* ----------------------------------------------------------- the project */
#project{position:fixed;inset:0;padding-top:78px}
#stage{position:absolute;inset:78px 0 0;user-select:none}
#stage .tcv_tree,#stage .tcv_toolbar{display:none!important}
#stage [class*="tcv"]{--tcv-bg-color:transparent;--tcv-bg-overlay-color:var(--panel)}
#stage .tcv_viewer,#stage .tcv_cad_view,#stage .tcv_cad_viewer{background:transparent!important}
#pin-layer{position:absolute;inset:0;pointer-events:none}
.model-pin{position:absolute;pointer-events:auto;width:23px;height:23px;display:grid;place-items:center;border-radius:50%;background:var(--acid);color:var(--on-acid);font-family:var(--mono);font-size:10px;transform:translate(-50%,-50%)}
.model-pin.region-pin{border-radius:5px}

/* THE PROJECT'S OWN TOP BAR. Nothing stands between the lockup and the centre:
   while the agent works the centre line carries the mark drawing itself and the
   sentence it is saying, and the right says BUILDING, how long, and Activity.
   Once the part has landed the mark has done its job and gone, and the state
   goes with it — a finished project does not announce that it is finished, the
   part is on screen and the record is in Activity. The left carries the way
   back to the list and nothing else: the project's own name is the thing you
   just came from, not something to read while looking at the model. */
body.in-project header{border-bottom:0}
body.in-project .chrome-right{margin-left:auto}
body.in-project #head-thought{position:absolute;left:50%;transform:translateX(-50%);max-width:min(620px,calc(100vw - 620px));margin:0;display:flex;align-items:center;gap:11px}
#head-thought>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#head-thought .compass{display:none;width:19px;height:19px}
#head-thought.working .compass{display:block}
body.in-project .run-state{gap:9px;font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--acid)}
body.in-project .run-state .dot{width:6px;height:6px}
body.in-project .run-state.attention{color:var(--warm)}
body.in-project #activity-toggle,body.in-project #resume{border:0;padding:0;font-size:12.5px;color:var(--ink-soft)}
body.in-project #activity-toggle:hover,body.in-project #resume:hover{color:var(--ink)}

/* THE PLAN. One line — how far along, a hairline, the step being worked on —
   and the whole of it when you ask, dropped over the model so nothing below it
   moves. It is a live thing: when the run ends the plan goes with it, and what
   it did is the part on the screen plus the record in Activity. */
#plan{position:absolute;left:40px;top:104px;width:min(540px,calc(100vw - 80px));z-index:5}
#plan-line{display:flex;align-items:flex-start;gap:12px;width:100%;text-align:left}
.plan-count{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-mute);white-space:nowrap;flex-shrink:0;padding-top:4px}
.plan-bar{width:64px;height:2px;margin-top:8px;background:rgba(226,216,192,.10);overflow:hidden;flex-shrink:0}
.plan-bar i{display:block;height:100%;width:0;background:var(--acid);transition:width .5s ease}
.plan-now{min-width:0;font-size:13px;line-height:1.45;color:var(--acid);overflow-wrap:anywhere}
.plan-caret{color:var(--ink-mute);font-size:11px;flex-shrink:0;padding-top:3px;transition:transform .24s cubic-bezier(.2,.75,.2,1)}
#plan.is-open .plan-caret{transform:rotate(180deg)}
#plan-steps{height:0;overflow:hidden;opacity:0;transition:height .24s cubic-bezier(.2,.75,.2,1),opacity .18s ease}
#plan.is-open #plan-steps{opacity:1}
.plan-rows{padding-top:12px}
/* Shut, the plan is one line over the void at the top left. Opened, it is six
   of them and they run across whatever the part happens to be, so the list
   takes a ground of its own — pale geometry underneath must not decide whether
   a step can be read. `planHeight` measures this box, padding included. */
#plan.is-open .plan-rows{padding:13px 15px;background:rgba(13,13,17,.94);border:1px solid var(--hair);border-radius:var(--radius)}
.plan-step{display:flex;align-items:baseline;gap:12px;padding:5px 0;font-size:13px;line-height:1.45;color:#8f948c}
.plan-step i{width:16px;flex-shrink:0;font-family:var(--mono);font-style:normal;font-size:10px;color:rgba(222,213,194,.30)}
.plan-step span{min-width:0;overflow-wrap:anywhere}
.plan-step.done,.plan-step.done i{color:#6b7166}
.plan-step.done i{font-family:var(--sans);font-size:12px}
.plan-step.done span{text-decoration:line-through;text-decoration-color:rgba(107,113,102,.55);text-decoration-thickness:1px}
.plan-step.current,.plan-step.current i{color:var(--acid)}

/* THE CONCEPT STUDIO — the picture where the model will be.
   It is what the user is judging, so it gets the stage and the size, and the
   controls stay at the edges exactly as they do around geometry. Nothing else
   competes with it: the viewer tools and the STEP corner
   have nothing to say before a build exists. */
#studio{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);width:min(760px,calc(100vw - 80px));text-align:center;z-index:5}
body.in-studio .deliver,body.in-studio #viewer-tools,body.in-studio #keyboard-help{display:none}
#studio .eyebrow{display:block;color:rgba(216,239,98,.72)}
#studio-frame{position:relative;margin-top:14px;min-width:min(460px,100%);min-height:300px;display:inline-grid;place-items:center;max-width:100%;border:1px solid var(--hair-strong);border-radius:var(--radius);background:rgba(13,13,17,.6);overflow:hidden}
#studio-image{display:block;max-width:100%;max-height:min(56vh,520px);width:auto;height:auto}
#studio-waiting{position:absolute;inset:0;display:grid;place-items:center;align-content:center;gap:14px;background:rgba(6,6,8,.72)}
#studio-waiting p{font-family:var(--serif);font-style:italic;font-weight:300;font-size:17px;color:#b6c1b5}
#studio-waiting .compass{opacity:.95;animation:breathe 2.8s infinite}
#studio-versions{display:flex;justify-content:center;flex-wrap:wrap;gap:7px;margin-top:14px;min-height:26px}
#studio-versions button{font-family:var(--mono);font-size:10px;letter-spacing:.14em;color:#7e837b;border:1px solid rgba(226,216,192,.12);border-radius:4px;padding:5px 9px}
#studio-versions button:hover{color:var(--ink);border-color:var(--hair-strong)}
#studio-versions button[aria-pressed=true]{background:var(--acid);border-color:var(--acid);color:var(--on-acid)}
#studio-note{margin-top:11px;font-size:12.5px;line-height:1.6;color:#8d968b}
#studio-note em{font-family:var(--serif);font-style:italic;color:#b6c1b5}
#studio-error{margin-top:10px;font-size:12.5px;color:var(--warm)}
/* The bar below is the studio's while one is open: it is wider, because it
   carries two decisions as well as the words. */
body.in-studio .steer-entry .entry-box{border-color:rgba(216,239,98,.30)}

#clarification{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:560px;max-width:calc(100% - 60px);background:rgba(13,13,17,.97);border:1px solid rgba(216,239,98,.34);border-radius:10px;padding:26px;z-index:7}
#clarification p{margin:16px 0 18px;font-size:17px;line-height:1.5;color:var(--ink)}
#clarification .eyebrow{color:var(--acid)}
#clarification .micro{display:block}

#activity-panel{position:absolute;right:40px;top:104px;bottom:34px;width:372px;background:rgba(13,13,17,.96);border:1px solid var(--hair-strong);border-radius:var(--radius);display:flex;flex-direction:column;overflow:hidden;z-index:7}
.panel-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:16px 18px 12px;border-bottom:1px solid rgba(226,216,192,.09)}
.panel-head .micro+.micro{letter-spacing:.12em;color:rgba(222,213,194,.24)}
#activity{padding:0 18px;overflow:auto;scrollbar-width:thin;scrollbar-color:#3f4a41 transparent}
.activity-item{padding:14px 0;border-top:1px solid rgba(226,216,192,.07)}
.activity-item:first-child{border-top:0}
.activity-kind{display:flex;align-items:center;gap:10px;font-family:var(--mono);font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:#8b9482;margin-bottom:8px}
.activity-kind time{color:#4f5a4f;letter-spacing:.04em}
.activity-text p{font-size:12.5px;line-height:1.6;color:#c0c6b7;overflow-wrap:anywhere}
.activity-text p+p{margin-top:8px}
.activity-text strong{font-weight:600;color:#e1e7dc}
.activity-item.error .activity-kind{color:#c99385}
.activity-item.error .activity-text p{color:var(--warm)}
.activity-item.steering .activity-kind{color:#a6ae8e}
/* A tool call is one dim line, never a panel of its own. */
/* A subagent's line is Faber's work at one remove: indented under the name of
   the piece it was given, on a hairline that runs the length of its turn. */
.activity-item.delegated{margin-left:13px;padding-left:13px;border-top:0;border-left:1px solid rgba(226,216,192,.1)}
.activity-item.delegated .activity-kind{color:#7d8a74}
.tool-activity.delegated[data-task] .activity-kind{display:flex;margin-bottom:6px}
.tool-activity{padding:7px 0;border-top:0}
.tool-activity .activity-kind{display:none}
.tool-activity .activity-text p{font-size:11.5px;line-height:1.55;color:#7f9787}
.tool-activity .activity-text p:before{content:'→ ';color:#516a58}
/* ...and the line opens, because "it ran probe" is not an answer to "what did
   it just do". Closed it reads as the same dim line; open it is the call the
   model actually made, verbatim, in the mono every other figure here uses. */
.tool-activity details summary{display:flex;align-items:baseline;gap:9px;list-style:none;cursor:pointer;font-size:11.5px;line-height:1.55;color:#7f9787}
.tool-activity details summary::-webkit-details-marker{display:none}
.tool-activity details summary:before{content:'→';color:#516a58;flex-shrink:0}
.tool-activity details summary:hover{color:#a9c0ae}
.tool-activity details summary .tool-say{flex-grow:1;min-width:0;overflow-wrap:anywhere}
.tool-activity details summary .tool-name{font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:#4f5a4f;flex-shrink:0}
.tool-activity details[open] summary{color:#c0c6b7}
.tool-activity details[open] summary .tool-name{color:var(--acid)}
.tool-args{margin:8px 0 4px 17px;max-height:230px;overflow:auto;scrollbar-width:thin;scrollbar-color:#3f4a41 transparent;border-left:1px solid rgba(226,216,192,.10);padding-left:11px}
.tool-args pre{margin:0;font-family:var(--mono);font-size:10.5px;line-height:1.65;color:#9aa8a0;white-space:pre-wrap;overflow-wrap:anywhere}
/* The stream keeps a caret while text is still arriving. */
.activity-item.activity_stream:last-child .activity-text p:last-child:after,
.activity-item.summary_stream:last-child .activity-text p:last-child:after{content:'';display:inline-block;width:6px;height:12px;margin-left:4px;vertical-align:-1px;background:var(--acid);opacity:.8;animation:blink 1.1s steps(1) infinite}

/* Capture, Demonstration and Motion are all conditional: the cluster is a frame
   around whatever is available, and nothing at all when none of them is. */
.viewer-tools:not(:has(> button:not([hidden]))){display:none}
.viewer-tools{position:absolute;left:40px;bottom:34px;display:flex;align-items:center;gap:2px;padding:3px;border:1px solid rgba(226,216,192,.12);border-radius:7px;background:rgba(13,13,17,.7);z-index:6}
.viewer-tools button{display:flex;align-items:center;gap:8px;padding:9px 12px;border-radius:5px;font-size:12px;color:#a8ada4}
.viewer-tools button svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7}
.viewer-tools button:hover{color:var(--ink);background:rgba(226,216,192,.06)}
.viewer-tools button.active{background:rgba(216,239,98,.12);color:var(--acid)}

.deliver{position:absolute;right:40px;bottom:34px;display:flex;align-items:center;gap:10px;z-index:6;transition:bottom .26s cubic-bezier(.2,.75,.2,1)}
#download{display:inline-flex;align-items:center;gap:10px;font-size:12.5px;color:var(--ink-2);border:1px solid var(--hair-strong);border-radius:7px;padding:9px 14px;transition:border-color .15s,color .15s}
#download:hover{color:var(--ink);border-color:rgba(226,216,192,.34)}
#download svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2}
#download[aria-disabled=true]{cursor:wait;opacity:.6}

/* Names the sub-assembly the cursor is over — the same one a click opens — and
   how big it is. The motion panel stands in exactly this corner: one or the
   other, never both, so the name never reads against the sliders. */
#hover-label{position:absolute;left:40px;bottom:104px;display:flex;align-items:center;gap:10px;padding:9px 11px;background:rgba(13,13,17,.9);border:1px solid rgba(226,216,192,.12);border-radius:7px;font-size:11.5px;color:var(--ink-2);pointer-events:none;z-index:6}
#hover-label i{font-family:var(--mono);font-style:normal;font-size:10px;letter-spacing:.03em;color:var(--ink-mute)}
#hover-label i:empty{display:none}
#motion-panel:not([hidden])~#hover-label{display:none}

/* ------------------------------------------- what the last build changed */
/* The answer is on the geometry: the parts that arrived light up and fade in.
   This chip only names the count and offers it again, so a build that landed
   while the tab was in the background can still be read afterwards. */
#change-note{position:absolute;left:50%;transform:translateX(-50%);top:104px;display:flex;align-items:center;gap:11px;padding:6px 8px 6px 13px;background:rgba(13,13,17,.92);border:1px solid rgba(216,239,98,.3);border-radius:7px;z-index:6;animation:change-in .5s ease-out}
#change-note .eyebrow{white-space:nowrap}
#change-replay{display:flex;align-items:center;gap:9px;padding:4px 8px;border-radius:5px;font-size:12px;color:var(--ink-2)}
#change-replay svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.7}
#change-replay:hover{color:var(--acid);background:rgba(216,239,98,.1)}
#change-dismiss{font-size:15px;line-height:1;color:#767c73;padding:2px 5px}
#change-dismiss:hover{color:var(--ink)}
@keyframes change-in{from{opacity:0;transform:translate(-50%,-7px)}to{opacity:1;transform:translate(-50%,0)}}

/* ----------------------------------------------- the component right-click */
/* Anchored where the pointer was, and clamped to the stage by viewer.js. It
   acts on ONE named component, so the name and its size lead, exactly as the
   hover label reads them. */
#part-menu{position:fixed;min-width:212px;max-width:260px;padding:11px;background:rgba(13,13,17,.97);border:1px solid var(--hair-strong);border-radius:var(--radius);z-index:13;box-shadow:0 14px 34px rgba(0,0,0,.5)}
#part-menu .menu-head{display:flex;flex-direction:column;gap:3px;padding:2px 5px 9px;border-bottom:1px solid var(--hair)}
#part-menu .menu-head strong{font-size:12.5px;font-weight:400;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#part-menu .menu-head i{font-family:var(--mono);font-style:normal;font-size:10px;letter-spacing:.03em;color:var(--ink-mute)}
#part-menu .menu-head i:empty{display:none}
/* A leaf inside a sub-assembly answers to two scopes. Naming both is the only
   way a click can mean the cup rather than the tray it sits on. */
.menu-scope{display:flex;gap:4px;margin:9px 0 3px}
.menu-scope button{flex:1;padding:5px 6px;border:1px solid var(--hair);border-radius:5px;font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:#8b9089;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu-scope button[aria-pressed=true]{border-color:rgba(216,239,98,.4);color:var(--acid);background:rgba(216,239,98,.08)}
.menu-item{display:flex;align-items:center;gap:9px;width:100%;margin-top:4px;padding:8px 7px;border-radius:5px;font-size:12px;color:#b6bbb2;text-align:left}
.menu-item svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.7}
.menu-item:hover{color:var(--ink);background:rgba(226,216,192,.06)}
.menu-item.quiet{color:#8b9089;font-size:11px}
.menu-slider{margin:9px 2px 3px}
.menu-slider .joint-label{margin-bottom:2px}
.menu-slider input{width:100%;accent-color:var(--acid);margin:9px 0 0}
#part-menu .menu-foot{margin-top:9px;padding-top:8px;border-top:1px solid var(--hair)}

/* THE ENTRY. One box, two faces. Shut it is a pill centred at the foot; open it
   is the panel — the same box, its width, height and radius on one ease while
   the faces cross over inside it, the shut one leaving at once and the open one
   arriving a hundred milliseconds in. Nothing is ever in two places: the square
   at the end of the shut row is the stop while a run is alive and nothing is
   written, and the send arrow the moment there is a sentence. */
.steer-entry{position:absolute;left:48px;right:48px;bottom:56px;display:flex;justify-content:center;z-index:7;transition:right .26s cubic-bezier(.2,.75,.2,1)}
/* Activity is a panel over the model's right edge, and a direction must stay
   writable while the log is being read: the entry gives it the room. */
#project:has(#activity-panel:not([hidden])) .steer-entry{right:452px}
.entry-box{position:relative;overflow:hidden;width:280px;height:54px;border-radius:9px;background:rgba(10,10,13,.90);border:1px solid var(--hair-strong);transition:width .26s cubic-bezier(.2,.75,.2,1),height .26s cubic-bezier(.2,.75,.2,1),border-radius .26s cubic-bezier(.2,.75,.2,1),border-color .2s ease,background-color .2s ease}
.entry-box:hover{border-color:rgba(226,216,192,.26)}
.steer-entry.is-open .entry-box{width:min(760px,100%);height:var(--entry-h,148px);border-radius:10px;background:rgba(10,10,13,.94)}
.steer-entry.is-open .entry-box:focus-within{border-color:rgba(226,216,192,.42)}
.steer-entry.has-notes .entry-box{border-color:rgba(216,239,98,.3)}
.entry-face{position:absolute;inset:0;transition:opacity .16s ease}
.face-shut{transition-delay:0s;display:flex;align-items:center;justify-content:center;gap:13px;height:100%;padding:0 12px 0 18px;cursor:pointer}
.face-open{transition-delay:.1s;opacity:0;pointer-events:none;display:flex;flex-direction:column;height:100%;padding:18px 18px 14px}
.steer-entry.is-open .face-shut{opacity:0;pointer-events:none}
.steer-entry.is-open .face-open{opacity:1;pointer-events:auto}
#steer-peek{font-size:14px;color:var(--ink-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#steer-peek.written{color:var(--ink-2)}
.entry-rule{width:1px;height:16px;background:var(--hair-strong);flex-shrink:0}
/* Before the first geometry there is nothing to comment on, so the pencil is
   gone and its divider goes with it rather than ruling off an empty space. */
.face-shut:has(#steer-comment[hidden]) .entry-rule{display:none}
#steer-comment{display:grid;place-items:center;width:22px;height:22px;color:var(--ink-soft);flex-shrink:0}
#steer-comment svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.9}
#steer-comment:hover,#steer-comment.active{color:var(--acid)}
.entry-square{display:grid;place-items:center;width:30px;height:30px;border-radius:7px;background:var(--acid);color:var(--on-acid);flex-shrink:0}
.entry-square svg{width:13px;height:13px}
.entry-square:hover{background:#e5f5a8}
.face-open textarea{flex-grow:1;font-size:16px;line-height:1.5;min-height:22px}
.face-open .file-chips{max-height:88px;overflow:auto}
.entry-row{display:flex;align-items:center;gap:18px;margin-top:10px}
.entry-row .clip{margin-left:-6px}
#steer-form #annotate{gap:7px;padding:0;font-size:12.5px;color:var(--ink-soft)}
#steer-form #annotate svg{width:14px;height:14px}
#steer-form #annotate:hover{color:var(--ink)}
#steer-form #annotate.active{color:var(--acid)}
#steer-button{margin-left:auto;padding:11px 17px;gap:11px}
#entry-close{position:absolute;right:16px;top:14px;font-size:15px;line-height:1;color:var(--ink-mute)}
#entry-close:hover{color:var(--ink-2)}
/* In the concept studio the row says what a message costs, in the micro voice. */
#steer-hint{flex-grow:1;font-family:var(--mono);font-size:10px;letter-spacing:.04em;color:#858d7c;line-height:1.4}
#steer-hint:empty{display:none}
#studio-cancel{margin-left:auto}
#studio-validate{padding:11px 17px;gap:11px}
#annotation-list .chip{border-color:rgba(216,239,98,.35);color:#dcdccc}
#annotation-list .chip span{cursor:pointer}

#motion-panel{position:absolute;left:40px;bottom:98px;width:250px;background:rgba(13,13,17,.96);border:1px solid var(--hair-strong);border-radius:var(--radius);padding:16px;max-height:280px;overflow:auto;z-index:7}
.joint-row{margin:13px 0 16px}
.joint-label{display:flex;justify-content:space-between;gap:8px;font-size:11px;color:#bfc4b6}
.joint-label output{font-family:var(--mono);color:var(--acid);font-size:10px;white-space:nowrap}
.joint-row input{width:100%;accent-color:var(--acid);margin:12px 0 0}
.joint-actions{display:flex;justify-content:space-between}
.joint-actions button{font-size:10px;color:#91a793}
.joint-actions button:hover{color:var(--acid)}

/* OPENING A PROJECT IS NOT INSTANT — the model has to be fetched and built —
   so the stage says what it is doing rather than sitting empty and looking
   broken. The mark is the loading state here too: the same swept arc that runs
   in the bar while the agent works. */
#project-loading{position:absolute;inset:78px 0 0;z-index:4;display:grid;align-content:center;justify-items:center;gap:16px;pointer-events:none;animation:fade-in .22s ease}
#project-loading .compass{width:76px;height:76px}
#project-loading .micro{color:var(--ink-soft);animation:breathe 2.2s ease-in-out infinite}

/* THE SWITCHER. Somewhere else to go without leaving where you are: the list
   drops from under the bar over the model, picking a project switches straight
   to it, and the page that holds all of them is one line away at the foot. */
#switcher{position:fixed;inset:0;z-index:20;background:rgba(4,4,6,.5);animation:fade-in .18s ease}
.switcher-panel{position:absolute;left:40px;top:70px;width:min(420px,calc(100vw - 80px));max-height:min(62vh,560px);display:flex;flex-direction:column;overflow:hidden;background:rgba(13,13,17,.98);border:1px solid var(--hair-strong);border-radius:10px;box-shadow:0 24px 62px rgba(0,0,0,.55);animation:sheet-in .26s cubic-bezier(.2,.75,.2,1)}
.switcher-panel:focus{outline:none}
@keyframes sheet-in{from{opacity:0;transform:translateY(-12px) scale(.985)}to{opacity:1;transform:none}}
.switcher-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:15px 18px 11px;border-bottom:1px solid rgba(226,216,192,.09)}
#switcher-list{overflow:auto;padding:6px 8px;scrollbar-width:thin;scrollbar-color:#3f4a41 transparent}
.switcher-row{display:flex;align-items:center;gap:12px;width:100%;padding:11px 10px;border-radius:6px;text-align:left;transition:background-color .15s ease,transform .15s ease}
.switcher-row:hover{background:rgba(226,216,192,.06)}
.switcher-row:active{transform:scale(.99)}
.switcher-row .dot{width:6px;height:6px}
.switcher-row .compass{width:17px;height:17px;margin:-4px -5px -4px -6px}
.switcher-row .dot.unread{background:var(--acid)}
.switcher-row .name{flex-grow:1;min-width:0;font-size:13px;color:var(--ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.switcher-row .elapsed{flex-shrink:0;font-family:var(--mono);font-size:10.5px;color:var(--ink-mute)}
/* The one you are already in is named, not offered again. */
.switcher-row.current{background:rgba(216,239,98,.06)}
.switcher-row.current .name{color:var(--acid)}
.switcher-row.current .elapsed{color:rgba(216,239,98,.5)}
.switcher-empty{padding:28px 12px;text-align:center;font-size:12.5px;line-height:1.6;color:var(--ink-soft)}
.switcher-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;padding:14px 18px;border-top:1px solid rgba(226,216,192,.09);font-size:12.5px;color:var(--ink-soft);transition:color .15s ease,background-color .15s ease}
.switcher-foot:hover{color:var(--ink);background:rgba(226,216,192,.04)}
.switcher-foot svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2}

#capture-overlay{position:absolute;inset:0;z-index:12;cursor:crosshair;background:rgba(0,0,0,.12);touch-action:none}
#capture-overlay p{position:absolute;bottom:30px;left:50%;transform:translateX(-50%);font-size:12px;background:var(--panel);padding:12px 20px;border-radius:8px;border:1px solid rgba(216,239,98,.33);pointer-events:none}
#capture-rect{position:absolute;border:1px solid var(--acid);background:rgba(216,239,98,.04);pointer-events:none}

/* ------------------------------------------------------- dialogs and toast */
dialog{background:#101014;color:var(--ink);border:1px solid var(--hair-strong);border-radius:10px;padding:26px;max-width:440px;width:calc(100% - 36px)}
dialog::backdrop{background:rgba(0,0,0,.55)}
dialog h2{font-size:19px;font-weight:400;margin:14px 0}
dialog textarea{background:rgba(8,14,12,.5);border:1px solid rgba(226,216,192,.13);padding:12px;border-radius:7px;font-size:13px;resize:vertical}
dialog img{width:100%;max-height:200px;object-fit:contain;border-radius:7px;margin-bottom:15px}
.dialog-buttons{display:flex;justify-content:end;gap:10px;margin-top:18px}
.dialog-head{display:flex;align-items:center;justify-content:space-between;gap:20px}
.dialog-head h2{margin:0 0 20px}
.dialog-head button{align-self:start;font-size:21px;color:#a2a69a}
#shortcuts-dialog{max-width:420px}
#shortcuts-dialog dl{margin:0}
#shortcuts-dialog dl>div{display:flex;justify-content:space-between;gap:18px;padding:11px 0;border-top:1px solid rgba(226,216,192,.09);font-size:12px}
#shortcuts-dialog dd{margin:0;white-space:nowrap}
kbd{font:10px var(--mono);color:#bec3b4;background:rgba(255,255,255,.04);border:1px solid rgba(226,216,192,.13);border-radius:3px;padding:3px 5px}
#shortcuts-dialog p{font-size:11px;line-height:1.7;color:#9ba38f;margin-top:20px}
#project-name{width:100%;padding:12px;background:rgba(8,14,12,.5);border:1px solid rgba(226,216,192,.13);border-radius:7px;color:var(--ink);font:inherit;font-size:14px}
#toast{position:fixed;z-index:50;bottom:150px;left:50%;transform:translateX(-50%);padding:12px 17px;background:var(--acid);color:var(--on-acid);border-radius:7px;font-size:12px;max-width:90vw}
#toast.error{background:#e6b09e;color:#3e1a12}

@keyframes breathe{50%{opacity:.35}}
@keyframes blink{50%{opacity:0}}

/* ------------------------------------------------------------------ motion */
/* NOTHING IN THIS PRODUCT JUST APPEARS. A press gives under the pointer and
   comes back, a surface rises into place, a panel arrives from the edge it
   belongs to, and a list deals itself out rather than landing all at once.
   Everything here is 450ms or under, and all of it goes when the machine says
   it does not want motion — the one media query at the end of this file. */
.primary,.ghost,.subtle,.clip,.pill,.entry-square,.filters button,.card-menu summary,.active-row,.wordmark,#download,#restore-session{transition-property:color,background-color,border-color,opacity,transform;transition-duration:.18s;transition-timing-function:ease}
.primary:active,.ghost:active,.entry-square:active,.clip:active,.card-menu summary:active,#download:active{transform:scale(.95)}
.pill:active,.subtle:active,.filters button:active,.wordmark:active,#restore-session:active{transform:scale(.94)}
.active-row:active{transform:translateX(3px)}
.project-card:active{transform:translateY(-1px) scale(.995)}
/* Waiting is a state you can see: the button that sent the work breathes. */
.primary:disabled{animation:breathe 1.4s ease-in-out infinite}

/* A surface rises the first time you land on it — home, the list, a project. */
#home,#projects-page,#project{animation:surface-in .42s cubic-bezier(.2,.75,.2,1) backwards}
@keyframes surface-in{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}

/* The list deals itself out. `backwards` and never `both`: once a card has
   arrived the animation must stop speaking for its transform, or the lift it
   takes under the pointer would never happen. */
.project-card{animation:card-in .44s cubic-bezier(.2,.75,.2,1) backwards}
.project-card:nth-child(2){animation-delay:45ms}
.project-card:nth-child(3){animation-delay:90ms}
.project-card:nth-child(4){animation-delay:135ms}
.project-card:nth-child(n+5){animation-delay:180ms}
@keyframes card-in{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.active-row{animation:row-in .34s ease backwards}
.active-row:nth-child(2){animation-delay:40ms}
.active-row:nth-child(n+3){animation-delay:80ms}
@keyframes row-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Panels arrive from the edge they live on, and the model's own furniture
   fades up over it rather than being switched on. */
#activity-panel:not([hidden]){animation:panel-right .3s cubic-bezier(.2,.75,.2,1)}
@keyframes panel-right{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
#plan:not([hidden]),.viewer-tools,.deliver{animation:surface-in .38s cubic-bezier(.2,.75,.2,1) backwards}
#motion-panel:not([hidden]),#presentation-panel:not([hidden]){animation:panel-up .3s cubic-bezier(.2,.75,.2,1)}
@keyframes panel-up{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
/* The question the agent stops to ask does not slide in from anywhere: it
   takes the middle of the model and settles. */
#clarification:not([hidden]){animation:centre-in .34s cubic-bezier(.2,.75,.2,1)}
@keyframes centre-in{from{opacity:0;transform:translate(-50%,-46%) scale(.97)}to{opacity:1;transform:translate(-50%,-50%)}}
/* An opened tool call unrolls its arguments. */
.tool-activity details[open] .tool-args{animation:args-in .24s ease}
@keyframes args-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

dialog[open]{animation:dialog-in .24s cubic-bezier(.2,.75,.2,1)}
dialog[open]::backdrop{animation:fade-in .24s ease}
@keyframes dialog-in{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
#toast:not([hidden]){animation:toast-in .32s cubic-bezier(.2,.75,.2,1)}
@keyframes toast-in{from{opacity:0;transform:translateX(-50%) translateY(12px)}to{opacity:1;transform:translateX(-50%)}}

/* ------------------------------------------------------------ narrow views */
@media(max-width:1240px){
  #activity-panel{width:320px}
  #motion-panel,#presentation-panel{bottom:150px}
  #project:has(#activity-panel:not([hidden])) .steer-entry{right:384px}
}
@media(max-width:1000px){
  header{padding:0 24px;gap:10px}
  .switcher-panel{left:24px}
  .entry{padding:36px 20px}
  #active,footer{max-width:calc(100% - 40px)}
  #projects-page{max-width:calc(100% - 40px)}
  .project-card .card-stage{width:46%}
  .project-card .thumb{width:100%;height:210px}
  .card-title{font-size:25px}
  #plan,#activity-panel{left:24px}
  #activity-panel{right:24px;left:auto}
  .viewer-tools,#motion-panel{left:24px}
  .deliver{right:24px}
  /* No room left in the bar for the agent's line beside the run state, and no
     room at the foot for the STEP beside the entry: the log carries the first,
     and the second steps up over the panel rather than under it. */
  body.in-project #head-thought{display:none}
  .steer-entry{left:24px;right:24px}
  #project:has(#activity-panel:not([hidden])) .steer-entry{right:368px}
  #project:has(.steer-entry.is-open) .deliver{bottom:calc(70px + var(--entry-h,148px))}
}
@media(max-width:680px){
  header{height:66px;padding:0 18px}
  #project-loading{inset:66px 0 0}
  .switcher-panel{left:18px;right:18px;top:60px;width:auto}
  .wordmark span{font-size:12px;letter-spacing:.3em}
  #home{min-height:calc(100vh - 66px)}
  .entry h1{font-size:29px}
  .composer{margin-top:34px}
  .composer textarea{font-size:16px;flex-basis:100%}
  .composer-bottom{flex-wrap:wrap;align-items:center;gap:14px}
  .entry-tools{width:100%;padding-bottom:0}
  .mode-switch{margin-left:auto}
  #project{padding-top:66px}
  #stage{inset:66px 0 0}
  .steer-entry,#project:has(#activity-panel:not([hidden])) .steer-entry{left:18px;right:18px;bottom:34px}
  .steer-entry.is-open .entry-box{width:100%}
  .face-open{padding:14px 14px 12px}
  .face-open textarea{font-size:15px}
  .entry-row{gap:14px}
  #steer-form #annotate span{display:none}
  #activity-panel{left:18px;right:18px;width:auto;top:92px;bottom:200px}
  #change-note{top:88px;max-width:calc(100vw - 48px)}
  #plan{display:none}
}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}}

/* ------------------------------------------------------ the demonstration */
/* The player the agent records: a viewing mode, so it takes the motion
   panel's corner and only one of the two is ever open. */
#presentation-panel{position:absolute;left:40px;bottom:98px;width:min(320px,calc(100vw - 60px));padding:16px;background:rgba(13,13,17,.96);border:1px solid var(--hair-strong);border-radius:var(--radius);z-index:7}
.presentation-heading{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12.5px;color:var(--ink-2)}
.presentation-heading button{font-size:18px;color:#a2a69a}
.presentation-heading button:hover{color:var(--ink)}
#presentation-caption{font-size:12.5px;line-height:1.6;color:#bfc4b6;margin:12px 0}
.presentation-controls{display:flex;align-items:center;gap:8px}
.presentation-controls button{font-size:12px;padding:7px 11px;border:1px solid rgba(226,216,192,.16);border-radius:var(--radius-sm);color:var(--ink-2)}
.presentation-controls button:hover:not(:disabled){color:var(--ink);border-color:rgba(226,216,192,.3)}
.presentation-controls button:disabled{opacity:.3;cursor:default}
#presentation-clips{width:100%;margin:8px 0;padding:6px;font:inherit;font-size:12px;color:var(--ink-2);background:#131317;border:1px solid var(--hair-strong);border-radius:var(--radius-sm)}
#presentation-seek{width:100%;margin:8px 0 12px;accent-color:var(--acid)}
#presentation-count{margin-left:auto;font-family:var(--mono);font-size:10px;letter-spacing:.04em;color:#7e837b}
@media(max-width:1000px){#presentation-panel{left:24px}}
@media(max-width:680px){#presentation-panel{left:18px;right:18px;width:auto;bottom:200px}}
