/* ═══════════════════════════════════════════════════════════════════════════
   The work-OS frame, applied to the LIVE conversation.

   ⛔ This is a SKIN, not a second product. Every id, class and behaviour on the
   page stays exactly where it was — read-aloud, the step chips, the module
   cards, the work cards, share, the plus menu, the queue. If this file is
   removed the page is what it was, which is the property that makes it safe to
   ship while the product keeps running.

   It activates only under <body class="os">, so it can be switched off from
   one place.
   ══════════════════════════════════════════════════════════════════════════ */

body.os.inthread{
  --bg:#111726; --ink:#eef1f8; --muted:#a2adc4; --faint:#768399;
  --line:rgba(163,178,216,.17); --line2:rgba(163,178,216,.30);
  --surf:rgba(163,178,216,.07); --surf2:rgba(163,178,216,.13);
  --fill:#eef1f8; --onfill:#111726;
  --panel:#182034; --panelT:rgba(24,32,52,.92);
  --glass:rgba(28,37,59,.62); --glassT:rgba(24,32,52,.54);
  --lift:0 1px 0 rgba(255,255,255,.06) inset, 0 12px 34px rgba(4,8,18,.42);
  --lift-2:0 1px 0 rgba(255,255,255,.08) inset, 0 22px 60px rgba(4,8,18,.52);
  --osDisp:'Space Grotesk',var(--f-disp,sans-serif);
  --osMono:'JetBrains Mono',ui-monospace,Menlo,monospace;
}
:root[data-theme="light"] body.os.inthread{
  --bg:#f8f9ff; --ink:#101426; --muted:#59647b; --faint:#8791a7;
  --line:rgba(67,73,112,.13); --line2:rgba(92,78,174,.25);
  --surf:rgba(12,18,32,.035); --surf2:rgba(12,18,32,.07);
  --fill:#0c1220; --onfill:#ffffff;
  --panel:#ffffff; --panelT:rgba(255,255,255,.94);
  --glass:rgba(250,251,255,.70); --glassT:rgba(252,252,255,.66);
  --lift:0 1px 0 rgba(255,255,255,.9) inset, 0 10px 28px rgba(24,32,56,.10);
  --lift-2:0 1px 0 rgba(255,255,255,.9) inset, 0 20px 52px rgba(24,32,56,.14);
}

/* THE PLANE. One photographic surface behind everything, with the brand light
   on top of it. ⛔ The overlay is the background TONE, never black — black is
   what killed the aurora in the prototype's first cut. */
/* ⛔ Painted from `.thread` but FIXED to the viewport, so it sits behind the
   rail and the dock as well — they are glass, and glass over nothing is just a
   grey panel. This is why the rail can be translucent at all. */
body.os.inthread .thread::before{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background:url(/art/os/bg-clay.webp) center/cover no-repeat;opacity:.80;
  filter:saturate(1.15) contrast(.98) brightness(1.5)}
body.os.inthread .thread::after{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(1250px 700px at 78% -20%,rgba(139,110,255,.20),transparent 60%),
             radial-gradient(900px 600px at 4% 106%,rgba(34,211,238,.11),transparent 62%),
             linear-gradient(180deg,rgba(17,23,38,.42),rgba(17,23,38,.72))}
/* ⛔ THE LIGHT PLANE WAS BEING ERASED BY ITS OWN OVERLAY. opacity .55, then
   grayscale(1), then a 74%-white wash on top — three reductions stacked, and
   the photograph arrived as flat paper. The whole point of the plane is that a
   person can see it at the edges of the glass. Kept light and calm, but
   PRESENT: less wash at the top where the rail and header sit, and the grey is
   partial so the image keeps a little of its own colour. */
/* ⛔ `bg-light.webp` IS NOT A BACKGROUND PLANE. Opened it: a magenta studio
   shot of a white 3D slab — a product image that had been wired in as the
   light-theme plane. No amount of opacity tuning was going to make that read
   as premium, and three sessions of CSS blamed the wash for it.
   The dark plane is the real artwork (an aurora over a dark surface), so the
   light theme wears the SAME photograph, lifted and cooled rather than
   replaced. One plane, two treatments — which is also why they can never drift
   apart again. */
:root[data-theme="light"] body.os.inthread .thread::before{
  background-image:url(/art/os/bg-clay.webp);opacity:.42;
  filter:brightness(2.18) saturate(1.02) contrast(.88)}
:root[data-theme="light"] body.os.inthread .thread::after{
  background:radial-gradient(1200px 680px at 84% -16%,rgba(139,110,255,.13),transparent 64%),
             radial-gradient(900px 560px at 2% 104%,rgba(34,211,238,.09),transparent 62%),
             linear-gradient(180deg,rgba(249,250,255,.22),rgba(247,249,255,.52))}
body.os.inthread .thread > *{position:relative;z-index:1}
body.os.inthread .threadArt{display:none}

/* THE HEADER stays put while the conversation scrolls under it. */
body.os.inthread .t-head{
  position:sticky;top:0;z-index:12;background:var(--glassT);
  backdrop-filter:blur(30px) saturate(1.35);border-bottom:1px solid var(--line);
  padding:13px 34px 14px;gap:10px}
body.os.inthread .t-head #thead{font:500 13px var(--osDisp);color:var(--ink)}
body.os.inthread .ctxTag,body.os .ansLang,body.os .shareBtn{
  font:400 11px var(--osMono);color:var(--muted);border:1px solid var(--line);
  border-radius:999px;padding:3px 10px;background:var(--surf)}
body.os.inthread .ctxTag:hover,body.os .shareBtn:hover{color:var(--ink);border-color:var(--line2)}

/* THE CONVERSATION, read at length. */
body.os.inthread .msgs{padding:26px 34px 10px;max-width:none}
body.os.inthread .m-you{
  font:500 15.5px/1.6 var(--f-body,Inter,sans-serif);color:var(--ink);
  background:none;border:0;padding:0;margin:22px auto 0;max-width:880px}
body.os.inthread .m-orc{
  background:none;border:0;padding:0 0 0 16px;margin:14px auto 0;max-width:880px;
  border-left:2px solid var(--line);font-size:15px;line-height:1.72;color:var(--muted)}
body.os.inthread .m-orc strong{color:var(--ink)}

/* The step chips: the product's own next moves, given room to be read. */
body.os.inthread .chip-lbl{
  font:500 9.5px/1 var(--f-body,Inter,sans-serif);letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);max-width:880px;margin:18px auto 8px}
body.os.inthread .chips{max-width:880px;margin:0 auto;gap:7px}
/* ── NEXT STEPS — the control a non-technical owner actually presses ───────
   ⛔ THE CHIPS ARE THE INTERFACE. Somebody who does not know what to ask next
      presses one; they are the most-used control in the product and they were
      four grey monospace rows stacked full-width, which reads as terminal
      output rather than as a choice. Three changes, each with a reason:

   1 · AN EQUAL-CELL GRID, not a column. Full width was the fix for a ragged
       wrap; the cost was that every step became a banner and none looked
       chosen. Cells are equal, text is left, and one column below 660px.
   2 · A SENTENCE IS NOT MONO. Mono is for numbers, ids and dates (app standard
       §4). A question set in mono is what made these read as machine output.
       The MARK stays mono — it is a symbol, not prose.
   3 · THE THREE KINDS BECOME THREE THINGS. `act` does something, and it is the
       only filled control below the answer, because pressing it makes the
       product ACT — that is the differentiator, and one loud button is honest
       where four are a menu. ⛔ At most one filled chip: if two arrive, the
       first keeps the fill and the rest render as questions. */
body.os.inthread .chips.steps{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  gap:7px;align-items:stretch}
body.os.inthread .chips.steps .chip{
  width:auto;max-width:none;text-align:left;justify-content:flex-start;
  font:500 13.5px/1.35 var(--f-body,Inter,sans-serif);
  padding:9px 14px;border-radius:999px;
  transition:border-color .16s cubic-bezier(.2,.8,.2,1),
             transform .16s cubic-bezier(.2,.8,.2,1),
             box-shadow .16s cubic-bezier(.2,.8,.2,1)}
/* the mark is a symbol, and symbols stay mono */
body.os.inthread .chips.steps .chip::first-letter{font-family:var(--osMono)}

/* calc — a number will be worked out from THEIR inputs */
body.os.inthread .chips.steps .chip.k-calc{
  border-color:var(--line2);background:var(--surf)}
/* act — the platform does something. One per answer, and it looks like it. */
body.os.inthread .chips.steps .chip.k-act{
  background:var(--fill);color:var(--onfill);border-color:transparent;
  border-radius:12px;font-weight:550}
body.os.inthread .chips.steps .chip.k-act:hover{
  filter:brightness(1.08);transform:translateY(-1px)}
body.os.inthread .chips.steps .chip:not(.k-act):hover{
  border-color:var(--line2);transform:translateY(-1px);
  box-shadow:0 6px 22px -12px rgba(4,8,18,.5)}
body.os.inthread .chips.steps .chip:active{transform:scale(.985)}
/* ⛔ A CHOICE ALREADY MADE MUST NOT STILL LOOK PRESSABLE. Four live buttons
   sitting above a newer answer invite a second press that re-asks a question
   already answered. The block stays VISIBLE — it is history — and stops being
   a control. */
body.os.inthread .chips.steps.spent{opacity:.45;pointer-events:none}
@media(max-width:700px){
  body.os.inthread .chips.steps{grid-template-columns:1fr} }
body.os.inthread .chip{
  border:1px solid var(--line);background:var(--surf);border-radius:11px;
  font:400 13px var(--osMono);color:var(--muted);padding:10px 14px;text-align:left}
body.os.inthread .chip:hover{border-color:var(--line2);color:var(--ink);background:var(--surf2)}
body.os.inthread .chip.mod{border-radius:11px}

/* Work cards and the goal card become glass over the plane. */
body.os.inthread .works,body.os .goalCard,body.os .ctxPanel{
  background:var(--glass);backdrop-filter:blur(22px);border:1px solid var(--line);
  border-radius:14px;box-shadow:var(--lift)}
body.os.inthread .goalWrap{max-width:880px;margin:0 auto;padding:16px 34px 0}

/* The composer: quiet, and it fills with ink only when focused. */
body.os.inthread .composer{padding:14px 34px 22px;background:none}
body.os.inthread .composer .cwrap{
  max-width:880px;margin:0 auto;border:1px solid var(--line2);border-radius:16px;
  background:var(--glass);backdrop-filter:blur(26px) saturate(1.3);box-shadow:var(--lift-2)}
body.os.inthread .composer .cwrap:focus-within{border-color:var(--line2)}
body.os.inthread .composer .pfx{color:var(--faint);font:400 12px var(--osMono)}
body.os.inthread .composer #in{color:var(--ink)}
/* ⛔ THE SHELL DOES NOT RESTYLE THE SEND BUTTON. Three rules here fought over
   it — one gave it a 9px square, one absolutely positioned it, one put it back
   in flow — while the second half of the pair was styled by none of them, so
   the two could not align and did not match. The pair is one component, owned
   by index.html; the shell's whole say is where it SITS. */

/* ⛔ The dock's own rules now live in os-dock.css. What remains here is only
   the space the conversation reserves for it. */
/* legacy dock rules removed */
body.os.inthread .osDock{display:none}
body.os.inthread .osDock{
  display:flex;position:fixed;top:64px;right:0;bottom:0;width:var(--wh-dock,324px);z-index:11;overflow:auto;
  border-left:1px solid var(--line);background:var(--glass);
  backdrop-filter:blur(26px) saturate(1.3);padding:16px 14px 92px;
  flex-direction:column;gap:17px}
body.os.inthread .osDock h4{
  font:500 10px/1 var(--f-body,Inter,sans-serif);letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);display:flex;justify-content:space-between;margin-bottom:9px}
body.os.inthread .osDock .sec{display:flex;flex-direction:column;gap:5px}
body.os.inthread .osRow{
  display:grid;grid-template-columns:28px minmax(0,1fr);gap:10px;align-items:center;
  padding:8px;border-radius:9px;border:1px solid var(--line)}
body.os.inthread .osRow img{width:28px;height:28px;object-fit:contain}
body.os.inthread .osRow .nm{font-size:12.5px;color:var(--ink)}
body.os.inthread .osRow .d{font-size:11px;color:var(--muted);margin-top:2px}
body.os.inthread .osDock .none{font-size:12px;color:var(--faint);padding:6px 8px}
@media (min-width:1180px){
  body.os.inthread .msgs,body.os.inthread .composer,body.os.inthread .t-head{padding-right:358px}
  /* ⚡ The dock is on screen here, so an app pane must stop where it starts. */
  body.os.inthread{--app-right:var(--wh-dock,324px)}
}
/* ⛔ And when the dock is hidden the gutter goes with it — a reserved strip of
   nothing was the other half of what the owner saw. */
@media (max-width:1179px){ body.os .osDock{display:none} body.os.inthread{--app-right:0px} }

/* ── the stranger's rail: what is left, what an account makes of it ─────── */
/* ⛔ THE SPACING WAS COMPOUNDED, NOT CHOSEN. `top:54px` (below the header) and
   `padding-top:70px` both applied, so the first card began 124px down and the
   rail opened with a hole. One offset, once: the header owns 54px, the rail
   starts under it with its own 14px of air. */
/* ⛔ ONE NUMBER, DECLARED ON THE BODY. The rail's width and the app column's
   left gutter are the same fact; when they were two, the pane covered the
   rail's last 14px. ⚠ It is declared HERE and not on `.osAnon` itself: a custom
   property inherits DOWN, so a value set on the rail is unreadable by the body
   rule that needs it — the gutter would silently fall back to its default. */
body.os.inthread{--os-anon-w:268px}
body.os.inthread .osAnon{
  position:fixed;left:0;top:0;bottom:0;width:var(--os-anon-w);z-index:11;overflow-y:auto;
  display:flex;flex-direction:column;gap:2px;padding:14px 10px 14px;
  border-right:1px solid var(--line);background:var(--glass);
  backdrop-filter:blur(34px) saturate(1.4);
  scrollbar-width:thin;scrollbar-color:var(--line2) transparent}
body.os.inthread .osAnon::-webkit-scrollbar{width:7px}
body.os.inthread .osAnon::-webkit-scrollbar-thumb{
  background:var(--line2);border-radius:99px;border:2px solid transparent;background-clip:padding-box}

/* ── the day, at the top, the way the concept has it ───────────────────── */
body.os.inthread .osDay{
  display:flex;align-items:center;gap:10px;margin-bottom:12px;
  border:1px solid var(--line);border-radius:14px;background:var(--surf);
  padding:11px 12px;box-shadow:var(--lift)}
body.os.inthread .osDay .d{flex:1;min-width:0}
body.os.inthread .osDay b{display:block;font:600 14px/1.15 var(--osDisp);color:var(--ink)}
body.os.inthread .osDay span{
  display:block;font-size:11.5px;color:var(--faint);margin-top:3px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body.os.inthread .osDay i{
  font-style:normal;font:600 11.5px/1 var(--osMono);min-width:22px;height:22px;
  display:grid;place-items:center;border-radius:99px;
  background:var(--amber,#e0922f);color:#1b1200;padding:0 6px}

/* ── whose shelf this is ───────────────────────────────────────────────── */
body.os.inthread .osWho{
  display:flex;align-items:center;gap:9px;padding:7px 6px 5px;margin-top:4px}
body.os.inthread .osWho .av{
  width:24px;height:24px;border-radius:99px;flex:none;display:grid;place-items:center;
  background:var(--surf2);color:var(--muted);font:600 10px/1 var(--osMono);
  border:1px solid var(--line)}
body.os.inthread .osWho b{
  flex:1;min-width:0;font:500 13px var(--f-body,Inter,sans-serif);color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body.os.inthread .osWho em{
  font-style:normal;font:400 10.5px/1 var(--osMono);color:var(--faint);
  border:1px solid var(--line);border-radius:99px;padding:3px 7px}
body.os.inthread .osAnon[hidden]{display:none}
body.os.inthread .osFree{
  border:1px solid var(--line);border-radius:13px;background:var(--surf);padding:11px 12px;
  margin-top:8px}
body.os.inthread .osFree .n{display:flex;align-items:baseline;gap:8px}
body.os.inthread .osFree .n b{font:600 24px/1 var(--osDisp);color:var(--ink)}
body.os.inthread .osFree .n span{font-size:12px;color:var(--muted)}
body.os.inthread .osFree .bar{display:flex;gap:4px}
body.os.inthread .osFree .bar i{flex:1;height:3px;border-radius:99px;background:var(--surf2)}
body.os.inthread .osFree .bar i.used{background:var(--fill)}
body.os.inthread .osFree p{font-size:11px;color:var(--faint);line-height:1.45;margin-top:9px}
body.os.inthread .osGhost{
  border:1px dashed var(--line2);border-radius:12px;padding:12px 13px;margin-top:12px}
body.os.inthread .osGhost b{display:block;font-size:13px;color:var(--muted)}
body.os.inthread .osGhost span{
  display:block;font-size:11.5px;color:var(--faint);margin-top:5px;line-height:1.45}
body.os.inthread .osCta{
  margin-top:auto;border:0;border-radius:999px;padding:11px;cursor:pointer;
  background:var(--fill);color:var(--onfill);font:500 13.5px var(--f-body,Inter,sans-serif)}
body.os.inthread .osCta:hover{opacity:.92}
/* the old example rail is replaced, not stacked beside it.
   ⛔ !important is not laziness here: the page assigns rail.style.display
   from JS in four places, and an inline style beats every stylesheet rule.
   Clearing the property from script instead would fight that code each time
   it runs. */
body.os.inthread #exRail{display:none!important}
body.os.inthread .thread.anonEx{padding-left:0}
@media (min-width:1180px){
  body.os.inthread .msgs,body.os.inthread .composer,body.os.inthread .t-head{padding-left:290px}
  /* ⚡ …and only while the rail is actually drawn: `osAnonOn` is set by the
     same code that shows it (os-thread.js), because a signed-in person never
     sees this rail and must not be given its gutter. */
  body.os.inthread.osAnonOn{--app-left:var(--os-anon-w,268px)}
}
@media (max-width:1179px){ body.os.inthread .osAnon{display:none} body.os.inthread{--app-left:0px} }

/* ── the composer was a narrow box in the middle of a wide screen ───────── */
/* ⛔ `.cwrap` is flex:1 inside a row whose own width nothing set, so it
   collapsed to its content. The BOX is the thing that must be 880px, and the
   field must fill it — not the other way round. */
body.os.inthread .composer{display:block}
body.os.inthread .composer .cwrap{
  width:100%;max-width:880px;margin:0 auto;box-sizing:border-box;padding:11px 13px}
body.os.inthread .composer #in{flex:1;width:100%;min-height:24px;font-size:15px}
/* (removed: absolutely positioning half a pair is what broke its alignment) */
body.os.inthread .composer{position:relative}
/* the line under the field is gone — an empty string leaves an empty bar */
body.os.inthread .tfoot{display:none}

/* ── the free block must not look like it is thinking ──────────────────── */
/* ⛔ It pulsed, and a pulsing panel beside a streaming answer reads as work in
   progress. Nothing here is working; it is a count. */
body.os.inthread .osFree,body.os.inthread .osFree *{animation:none!important;transition:none}
body.os.inthread .osFree{background:none;border-color:var(--line);padding:11px 12px}
body.os.inthread .osFree .n b{font-size:19px}
body.os.inthread .osFree .n span{font-size:11.5px}
body.os.inthread .osFree p{font-size:11px;margin-top:8px}

/* ── the dock: same material as the rest of the concept ────────────────── */
body.os.inthread .osDock h4{padding:0 2px}
body.os.inthread .osDock .none{
  border:1px dashed var(--line);border-radius:10px;padding:10px 11px;color:var(--faint)}

/* ⛔ `width:100%` was applied and still resolved to 232px, because the row is
   laid out by the page's own flex rules that survive underneath. Rather than
   fight them selector by selector, the composer becomes an explicit flex row
   here and the field is told to take the space. Measured, not assumed. */
body.os.inthread .composer{display:flex;justify-content:center}
body.os.inthread .composer .cwrap{
  flex:1 1 auto;width:auto;min-width:0;max-width:880px}
body.os.inthread .composer .cwrap textarea#in{flex:1 1 auto;min-width:0;width:100%}
/* The container was a COLUMN with centred items, so a grow factor had no
   free space on the main axis and the box shrank to its content. */
body.os.inthread .composer{flex-direction:row;align-items:stretch}

/* ⛔ THE NARROW FIELD WAS MY OWN ARITHMETIC. I padded the composer by the two
   rail widths (290 + 358) to clear them, but the element is only 880 wide — so
   its content box was 232px and the field shrank to exactly that. The rails are
   FIXED overlays; the composer should span the row and reserve space with
   margins, not eat its own width with padding. */
/* ⛔ `width:100%` IS LOAD-BEARING HERE AND REMOVING IT COLLAPSED THE COMPOSER.
   I took it out under "one width owner" and was wrong about which owner:
   in the shell the composer SPANS THE ROW and reserves the two rails with
   padding (286px + 348px = 634px, below). With index.html's
   `width:min(--wh-chat,880px)` of 660px and border-box, the content box became
   660 − 634 = 26px — a column one character wide, exactly what the owner
   photographed three times.
   ⚡ THE INVARIANT IS ONE OWNER PER CONTEXT, NOT ONE OWNER FULL STOP. The page
      and the shell are two layout systems: the page centres a 880px column with
      auto margins; the shell spans the row and pads. Each owns its own width and
      neither may reach into the other. test-boot measures the RESULT — the
      textarea's real width in a browser — because a grep cannot tell a
      load-bearing declaration from a duplicate one. */
body.os.inthread .composer{
  width:100%;box-sizing:border-box;padding:14px 24px 22px;margin:0}
@media (min-width:1180px){
  body.os.inthread .composer{padding-left:286px;padding-right:348px}
  body.os.inthread .msgs,body.os.inthread .t-head{box-sizing:border-box;width:100%}
}

/* the send button belongs on the same line as the field, not below it */
body.os.inthread .composer .cwrap{align-items:center}
body.os.inthread .composer .cwrap .pfx{flex:none}
body.os.inthread .composer .sendPair{align-self:center;flex:none;margin-left:10px}

/* ═══════════════════════════════════════════════════════════════════════════
   THE HEADER, as the concept has it: a real bar with a bottom edge, the mark
   hard left, and one cluster hard right. Nothing floats.

   ⛔ In the conversation the bar had no edge and no row, so `Ienākt` and the
   language pill hung in space over the reading column and the alignment read
   as broken. It is the same bar signed in or out — only the last control
   changes, from a person to a way to become one.
   ══════════════════════════════════════════════════════════════════════════ */
body.os.inthread .top{
  position:fixed;top:0;left:0;right:0;z-index:30;
  display:flex;align-items:center;gap:12px;
  height:54px;padding:0 18px 0 20px;
  border-bottom:1px solid var(--line);
  background:var(--glassT);backdrop-filter:blur(26px) saturate(1.3)}
body.os.inthread .top .logo{position:static;transform:none;left:auto;flex:none}
body.os.inthread .top .logo svg{height:24px;width:auto}
body.os.inthread .top .sp{flex:1}
/* what the bar is NOT for: a promise line, a second catalogue, a system tab */
body.os.inthread .top .topPromise,
body.os.inthread .top .sysbtn{display:none}

/* every control in the cluster is the same pill, so the row reads as one row */
body.os.inthread .top .auth button,
body.os.inthread .top .auth a,
body.os.inthread .top #arvPill,
body.os.inthread .top .hsearch{
  display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 13px;
  border:1px solid var(--line);border-radius:999px;background:var(--surf);
  color:var(--ink);font:400 12.5px var(--f-body,Inter,sans-serif);white-space:nowrap}
body.os.inthread .top .auth button:hover,
body.os.inthread .top #arvPill:hover,
body.os.inthread .top .hsearch:hover{border-color:var(--line2);background:var(--surf2)}
body.os.inthread .top #arvPill .pav{width:20px;height:20px}
/* the signed-in person is the last thing on the row, as in the concept */
body.os.inthread .top .auth{display:inline-flex;align-items:center;gap:8px;order:9}

/* the thread starts below the bar rather than under it */
body.os.inthread .t-head{top:54px}
body.os.inthread .thread{padding-top:54px}
/* ⛔ The rail's own `top` is 0 and its padding starts the content — see the
   compounded-spacing note above. Only the dock is offset here. */
body.os.inthread .osDock{top:54px}
body.os.inthread .osAnon{top:54px;padding-top:14px}

/* ⛔ THE MARK WAS DARK ON DARK. The brand SVG takes its ink from a variable the
   light page sets; inside the conversation the surface flipped and nobody told
   the logo. A mark you cannot see is worse than no mark — it reads as a broken
   image in the one place a person checks they are still on your site. */
body.os.inthread .top .logo{--bc-logo-ink:var(--ink);color:var(--ink)}
body.os.inthread .top .logo svg{color:var(--ink)}
body.os.inthread .top .logo svg [fill]:not([fill="none"]){fill:currentColor}

/* the bar needs a floor you can actually see over a photograph */
body.os.inthread .top{
  background:color-mix(in srgb, var(--panel) 78%, transparent);
  box-shadow:0 1px 0 var(--line)}

/* ── the thinking strip: the icon needs room, and it must not touch the row
      of suggestions under it ───────────────────────────────────────────── */
body.os.inthread .m-orc.think,body.os.inthread #think{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:10px 13px;
  min-height:68px;margin:18px auto;padding:14px 17px 12px;border-radius:16px;overflow:visible;
  border:1px solid color-mix(in srgb,var(--violet) 34%,var(--line));
  background:linear-gradient(125deg,color-mix(in srgb,var(--violet,#7c5cff) 10%,var(--glassT)),color-mix(in srgb,var(--cyan,#22d3ee) 7%,var(--glassT)));
  box-shadow:var(--lift)}
body.os.inthread #think .sp{display:none}
body.os.inthread #think .bar{grid-column:1/-1;width:100%;margin-top:2px}
body.os.inthread #think #tlabel{font-size:14px;font-weight:520;line-height:1.35;white-space:normal}
body.os.inthread #think .bl,body.os.inthread #think img,body.os.inthread #think svg{
  margin-left:2px;flex:none}

/* ⛔ THE ANSWER GREW SIDEWAYS AS IT STREAMED. The block was sized by its
   content, so each token widened it until it hit the cap — a paragraph that
   crawls outward while you read it. The reading column is a fixed measure from
   the first character. */
body.os.inthread .msgs > *{width:100%;max-width:880px;margin-left:auto;margin-right:auto}
body.os.inthread .m-orc,body.os.inthread .m-you{width:100%;box-sizing:border-box}

/* the sticky suggestions must not sit on the composer's edge */
body.os.inthread .sticky{padding-bottom:10px}
body.os.inthread .sticky .inner{gap:8px}

/* read-aloud belongs where the answer ends, not hidden */
body.os.inthread .m-orc .rd,body.os.inthread .m-orc [data-read]{
  opacity:1;border:1px solid var(--line);border-radius:999px;padding:4px 11px}

/* the count reads as a sentence, and the segments carry the arithmetic */
body.os.inthread .osFree .ttl{
  font:500 13px/1.4 var(--f-body,Inter,sans-serif);color:var(--ink)}
body.os.inthread .osFree.spent .ttl{color:var(--amber)}
body.os.inthread .osFree .bar{margin-top:10px}
body.os.inthread .osFree .bar i{height:4px}

/* ⚡ ONE PHOTOGRAPH, TWO TREATMENTS (owner, 2026-08-29). This file used to
   define the light plane correctly and then kill it six hundred lines later
   with `content:none` — so light shipped as flat paper while the CSS above
   read as if it had a backdrop. The argument for killing it was that a
   photograph competes with the words; the answer is not to remove the picture
   but to put PAPER UNDER THE WORDS and leave the picture at the edges, which
   is what `.msgs-light` below does.
   ⛔ Do not re-add a blanket kill here. If light ever looks noisy again, the
      fix is the reading light's opacity, not the plane's existence — the two
      themes wear the same photograph on purpose, and that is what stops them
      drifting into two designs. */

/* ── THE READING LIGHT — paper under the words, plane at the edges ────────
   A fixed wash between the rail and the dock, so the column you read sits on
   its own surface while the aurora stays visible past the furniture. ⛔ Fixed,
   not scrolled: a gradient that moves with the text is a gradient a reader
   notices, and this one must never be noticed. */
body.os.inthread .thread::before{z-index:0}
body.os.inthread .msgs::before{
  content:'';position:fixed;left:var(--app-left,0);right:var(--app-right,0);top:var(--wh-top,54px);bottom:0;z-index:0;
  pointer-events:none;
  background:linear-gradient(180deg,rgba(163,178,216,.085),rgba(163,178,216,.03) 55%,transparent)}
:root[data-theme="light"] body.os.inthread .msgs::before{
  background:linear-gradient(180deg,rgba(255,255,255,.55),rgba(255,255,255,.30) 55%,transparent)}
@media(max-width:1179px){ body.os.inthread .msgs::before{left:0;right:0} }
body.os.inthread .msgs > *{position:relative;z-index:1}

/* ── the answer's mark sits ON the text baseline, not above it ──────────── */
/* ⛔ The mark was a 26px badge beside 11.5px letter-spaced type, so its optical
   centre floated above the word and the pair read as two separate things. Same
   height as the line, same centre, one gap. */
body.os.inthread .m-orc .who{
  display:flex;align-items:center;gap:9px;line-height:1;
  margin-bottom:12px;letter-spacing:.1em}
body.os.inthread .m-orc .who svg,
body.os.inthread .m-orc .who img{
  width:18px;height:18px;flex:none;display:block;border-radius:5px}
body.os.inthread .m-orc .who .brain{margin:0}

/* ⛔ THE MARK WAS CLIPPED BY THE ANSWER'S OWN RULE. `.m-orc` carries a 2px
   left border and 16px of padding; the badge sat at the very edge and its
   rounded corner was cut in half. Give it the same left inset as the text it
   labels, so the two line up on one axis. */
body.os.inthread .m-orc .who{padding-left:2px;overflow:visible}
body.os.inthread .m-orc .who svg,body.os.inthread .m-orc .who img{margin-left:0}

/* ⛔ THE MARK WAS CROPPED BY ITS OWN viewBox, not by the layout — measured, it
   starts 20px INSIDE the answer block, so nothing was cutting it from outside.
   The contour geometry reaches past the box the mark is sliced from, and a
   fixed square forced the rest off. Let it keep its shape and draw outside. */
body.os.inthread .m-orc .who svg{
  width:auto;height:17px;overflow:visible;flex:none}

/* ⛔ THE FLOATING DOMAIN PILL IS GONE FROM THE CONVERSATION. `#rail` is the
   bottom-right stack of `.dz` chips, created only AFTER a site is analysed —
   which is why an earlier probe of mine reported no such element and I
   believed it. The dock's Konteksts section now names the page in the
   conversation, so the same fact was being told twice, once as furniture
   floating over the reading column. */
body.os.inthread #rail,body.os.inthread .rail{display:none!important}




/* ══ THE WORKSPACE PALETTE — THE CONCEPT'S, NOT AN APPROXIMATION ═══════════
   Owner, 2026-08-28: "colors, fonts, icons, styling was superior in the v3
   concept." Measured token by token against proto/ui.css, and he is right in a
   way I could not see by eye:

     --bg     #111726 navy   ← ours #04070d, near black
     --panel  #182034        ← ours #0a1120
     --muted  #a2adc4        ← ours #8b96ac, dimmer
     --surf   .07            ← ours .05, flatter
     --line   .17            ← ours .14, fainter

   Ours was uniformly darker, flatter and lower-contrast — every surface a
   little closer to the background, every edge a little less present. That is
   not a mood, it is why the screen read as cheap: on a near-black ground a
   panel cannot be seen to be a panel.

   And TEN tokens did not exist for us at all: --fill / --onfill (the
   instrument surface: graphite, never a gradient), --glass / --glassT,
   --lift / --lift-2 (the elevation), --r / --r-s (the radius scale), --rose.
   Every accent I hand-wrote was an approximation of a colour that already had
   a name in the design system.

   ⛔ SCOPED TO THE WORKSPACE, not to :root. The landing has its own palette
      and the owner already called that screen superior — it is not ours to
      restyle in this pass. */
body.workHomeOpen{
  --bg:#111726; --ink:#eef1f8; --muted:#a2adc4; --faint:#768399;
  --line:rgba(163,178,216,.17); --line2:rgba(163,178,216,.30);
  --surf:rgba(163,178,216,.07); --surf2:rgba(163,178,216,.13);
  --panel:#182034; --panelT:rgba(24,32,52,.92);
  --violet:#7c5cff; --cyan:#22d3ee; --lime:#a3e635;
  --mint:#5ee0a0; --amber:#fbbf24; --rose:#fb7185;
  --aurora:linear-gradient(100deg,#7c5cff,#22d3ee 55%,#a3e635);
  /* the instrument surface: graphite, never a gradient */
  --fill:#e8ecf6; --fill-2:rgba(232,236,246,.30); --onfill:#04070d;
  --glowA:rgba(139,110,255,.20); --glowB:rgba(34,211,238,.11);
  --glass:rgba(28,37,59,.62); --glassT:rgba(24,32,52,.54);
  --lift:0 1px 0 rgba(255,255,255,.06) inset, 0 12px 34px rgba(4,8,18,.42);
  --lift-2:0 1px 0 rgba(255,255,255,.08) inset, 0 22px 60px rgba(4,8,18,.52);
  --r:14px; --r-s:10px;
  background:var(--bg);
}
:root[data-theme="light"] body.workHomeOpen,
body.workHomeOpen:where([data-theme="light"] *){
  --fill:#0c1220; --fill-2:rgba(12,18,32,.24); --onfill:#ffffff;
  --bg:#f8f9ff; --ink:#101426; --muted:#59647b; --faint:#8791a7;
  --line:rgba(67,73,112,.13); --line2:rgba(92,78,174,.25);
  --surf:rgba(12,18,32,.035); --surf2:rgba(12,18,32,.07);
  --panel:#ffffff; --panelT:rgba(255,255,255,.94);
  --violet:#6b46e5; --cyan:#0891b2; --mint:#0f9d63; --amber:#b45309; --rose:#e11d48;
  --glass:rgba(250,251,255,.70); --glassT:rgba(252,252,255,.66);
  --lift:0 1px 0 rgba(255,255,255,.9) inset, 0 10px 28px rgba(24,32,56,.10);
  --lift-2:0 1px 0 rgba(255,255,255,.9) inset, 0 20px 52px rgba(24,32,56,.14);
}

/* The dock is a PANEL on that ground — it was inheriting a glass built for a
   near-black page and reading as a hole rather than a surface. */
body.workHomeOpen .osDock{background:var(--glass);border-left:1px solid var(--line);
  box-shadow:var(--lift)}


/* ══ THE RAIL ═════════════════════════════════════════════════════════════
   ⛔ TWELVE OF THE CONCEPT'S RAIL RULES WERE NEVER COPIED, and they were the
   ones doing the work. The first pass took proto/ui.css 80–112 and stopped —
   but the rail's other rules live at 294, 438, 560 and 576, hundreds of lines
   away under headings that do not say "rail". So our markup emitted
   `.sbjrow` and `.chv` with NOTHING styling them: no row hover, no `.here`
   selection, an unstyled chevron button, a square avatar where the concept has
   a round filled one, and every room kind the same grey.
   ⚡ It reads as v3 now because the rules are GENERATED, not copied: the ranges
      live in tools/scope-proto-css.mjs, where a range nobody added is visible.
      A rule nobody copied is invisible everywhere.
   ⛔ The rules themselves are in the GENERATED block below. What stays here is
      only what the concept's page gets from a global reset we do not share, or
      from an asset path that is ours. */

/* the room-kind artwork, sized — the concept ships PNGs where we had glyphs */
body.workHomeOpen .whAppNav .km{width:17px;height:17px;object-fit:contain;display:block;filter:drop-shadow(0 1px 2px rgba(4,8,18,.45))}
/* ⛔ Our two `.mk.logo` overrides are GONE. They said transparent + cover where
   the concept says a white tile + contain, and a customer's mark is usually
   dark ink on white — cropped and unlit on a dark rail. The generated block
   below carries the concept's pair; two answers to one question is how the
   paste starts drifting. */
body.workHomeOpen .whAppNav .sbjwrap{display:block}
body.workHomeOpen .whAppNav .addPlace{margin-top:auto}
/* buttons need their browser chrome removed; the concept's markup used <button>
   with a global reset we do not share. */
body.workHomeOpen .whAppNav .sbj,
body.workHomeOpen .whAppNav .room,
body.workHomeOpen .whAppNav .add,
body.workHomeOpen .whAppNav .chv,
body.workHomeOpen .whAppNav .today{background:none;border:0;cursor:pointer;font:inherit;color:inherit}


/* ══ THE COMPANY HOME — proto/app.js renderCompany, proto/ui.css pasted ══════
   The single largest gap the v3 handover named (§3.1): the concept's main area,
   when you open a company, is a HOME PAGE — rooms, a 4-up apps grid, goals with
   a measured position. Ours was a chat greeting. No CSS closes that, because it
   was a screen that did not exist rather than a screen that looked wrong.

   ⛔ EVERYTHING BELOW THE `GENERATED` MARKER IS A PASTE. It is emitted by
      `node tools/scope-proto-css.mjs`, which reads named line ranges out of
      proto/ui.css and adds one thing: the `body.workHomeOpen .whHome` scope.
      Declaration bodies are byte-for-byte the concept's.
   ⛔ Do not hand-edit it. Change proto/ui.css and re-run the tool — otherwise
      the two drift and the whole exercise (six rejected rounds) was pointless.
   ⚠ The one deliberate difference is a NAME, not a value: the concept's
     entrance keyframe is the global identifier `f`, which os.css already owns,
     so the tool renames it `whHomeIn`. */

/* ── ours: the ground, and the lift that keeps it a ground ────────────────── */
/* ⛔ EVERY OTHER CHILD OF THE SHELL SITS ABOVE IT. Without that the plane is
   just the last thing painted and covers the interface — which is exactly how
   `body::after` behaved for two rounds before this. */
/* ⛔ FIXED AND AT BODY LEVEL, z-index 0 — not absolute inside the shell. The
   shell is a stacking context at 9, so a plane inside it paints over the thread
   at 5 no matter what z-index it carries, and that veil over every answer is
   what three rounds of wash-tuning could not remove. Order: plane 0 < thread 5
   < shell 9. */
body.workHomeOpen .whPlane{position:fixed;inset:0;z-index:0;pointer-events:none}
/* ⚡ ONE KNOB, AND IT IS A DELIBERATE DEVIATION FROM v3 — the owner's, asked for
   three times: "still just a little bit lighter". The pasted plane matches the
   concept to within two points of luminance (measured region by region), so
   anything lighter than that is a CHOICE, not a fix, and it belongs here rather
   than inside the paste where it would look like the concept's own value.
   ⛔ Do not edit the generated block to change this. `--wh-lift:1` is exact
      parity with v3; the plane's own `brightness(1.5)` is multiplied by it. */
body.workHomeOpen{--wh-lift:1.14}
body.workHomeOpen .whPlane::before{filter:saturate(1.15) contrast(.98) brightness(calc(1.5 * var(--wh-lift,1)))}
body.workHomeOpen .whAppNav,
body.workHomeOpen .whHome,
body.workHomeOpen .whPanel,
body.workHomeOpen .whArrival,
body.workHomeOpen .whMobile,
body.workHomeOpen .whToast,
body.workHomeOpen .whLoading{z-index:1}

/* ── ours: the surface the pasted rules live on ───────────────────────────── */
/* ⛔ THE DOCK IS `position:fixed; z-index:11` AND THIS SHELL IS z-index 9, so
   a home laid out as `inset:0 0 0 var(--wh-nav)` runs UNDERNEATH it — the
   right-hand third of every block clipped by a panel that looks like it is
   part of the page. That is the same fault the conversation had (it reserved
   the rail's width and not the dock's) and it is not a styling problem: it is
   a column never given its width back. Both sides, at the same breakpoint the
   thread uses, so the two never disagree about whether the dock is there. */
/* ⛔ AND IT IS NOT OPAQUE. `background:var(--bg)` here painted a flat slab over
   the plane, so every `--glass` panel on it was glass over a wall — which is
   exactly the "it feels heavy, it should be lighter" the owner reported. The
   blocks bring their own glass and their own lit top edge; the page underneath
   them is the photograph. */
body.workHomeOpen .whHome{position:absolute;inset:0 var(--wh-dock) 0 var(--wh-nav);pointer-events:auto;
  background:transparent;overflow-y:auto;overscroll-behavior:contain;
  display:flex;flex-direction:column}
@media(max-width:1180px){body.workHomeOpen .whHome{right:0}}
/* The concept's markup used <button> under a global reset we do not share. */
body.workHomeOpen .whHome .gchip,body.workHomeOpen .whHome .ask .opts button,
body.workHomeOpen .whHome .ln,body.workHomeOpen .whHome .grow,body.workHomeOpen .whHome .appc,
body.workHomeOpen .whHome .rh1 .crumb,body.workHomeOpen .whHome .rh2 .give{
  background:none;border:0;font:inherit;color:inherit;cursor:pointer}
body.workHomeOpen .whHome button.ln,body.workHomeOpen .whHome button.grow{border-top:1px solid var(--line)}
body.workHomeOpen .whHome div.ln{cursor:default}
body.workHomeOpen .whHome .ln .t .km{width:17px;height:17px;object-fit:contain;display:block}
body.workHomeOpen .whHome .ln .t{display:flex;align-items:center;gap:6px}
body.workHomeOpen .whHome .appc{cursor:pointer}
/* ── ours: an empty room says which room it is ────────────────────────────── */
/* ⛔ TWO EMPTY ROOMS LOOKED IDENTICAL — both blank — so a correct switch
   between them was invisible, and four rounds went into a click that was
   working the whole time. What distinguishes one empty room from another is
   the room saying what it is. */
body.workHomeOpen .whRoomEmpty{position:absolute;top:0;left:var(--wh-nav);right:var(--wh-dock);bottom:0;
  z-index:1;pointer-events:auto;display:flex;flex-direction:column;justify-content:center;
  gap:12px;padding:90px 34px 140px;max-width:none}
@media(max-width:1180px){body.workHomeOpen .whRoomEmpty{right:0}}
@media(max-width:860px){body.workHomeOpen .whRoomEmpty{left:0;padding:80px 18px 130px}}
body.workHomeOpen .whRoomEmpty .mk{width:34px;height:34px;display:grid;place-items:center;
  font:400 20px var(--mono);color:var(--faint)}
body.workHomeOpen .whRoomEmpty .mk .km{width:32px;height:32px;object-fit:contain;display:block}
body.workHomeOpen .whRoomEmpty h1{font:600 27px/1.15 var(--disp);letter-spacing:-.02em;color:var(--ink);margin:0}
body.workHomeOpen .whRoomEmpty p{font:400 14px/1.6 var(--body);color:var(--muted);margin:0;max-width:56ch}
body.workHomeOpen .whRoomEmpty .asks{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
body.workHomeOpen .whRoomEmpty .asks button{padding:8px 14px;border-radius:999px;border:1px solid var(--line2);
  background:var(--surf);color:var(--ink);font:400 13px var(--body);cursor:pointer}
body.workHomeOpen .whRoomEmpty .asks button:hover{background:var(--surf2);border-color:var(--fill-2)}
body.workHomeOpen .whRoomEmpty .sets{align-self:flex-start;margin-top:4px;background:none;border:0;
  color:var(--faint);font:400 12px var(--body);cursor:pointer;padding:2px 0}
body.workHomeOpen .whRoomEmpty .sets:hover{color:var(--ink)}

/* ── ours: a room says which room it is, over its own conversation ────────── */
/* ⛔ Without this a room's thread is indistinguishable from the company's, and
   that is exactly what the owner saw: a room "opened" and nothing on screen
   changed. It reuses the concept's own `.rh1` grammar (see the GENERATED block)
   rather than inventing a second header language. */
body.workHomeOpen .whRoomHead{position:absolute;top:0;left:var(--wh-nav);right:var(--wh-dock);z-index:2;
  pointer-events:auto;background:var(--glassT);backdrop-filter:blur(30px) saturate(1.35);
  border-bottom:1px solid var(--line);padding:13px 34px 14px}
@media(max-width:1180px){body.workHomeOpen .whRoomHead{right:0}}
@media(max-width:860px){body.workHomeOpen .whRoomHead{left:0;padding:11px 16px 12px}}
body.workHomeOpen .whRoomHead .rh1{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--muted)}
body.workHomeOpen .whRoomHead .rh1 .crumb{color:var(--muted);border:0;background:none;cursor:pointer;
  font:inherit;border-radius:6px;padding:1px 3px}
body.workHomeOpen .whRoomHead .rh1 .crumb:hover{color:var(--ink)}
body.workHomeOpen .whRoomHead .rh1 .sep{color:var(--faint)}
body.workHomeOpen .whRoomHead .rh1 .rm{color:var(--ink);font-weight:500;display:flex;align-items:center;gap:7px}
body.workHomeOpen .whRoomHead .rh1 .rm .km{width:16px;height:16px;object-fit:contain;display:block}
body.workHomeOpen .whRoomHead .rh1 .kind{font:400 10px var(--mono);color:var(--faint);
  border:1px solid var(--line);border-radius:5px;padding:1px 7px}
body.workHomeOpen .whRoomHead .rh1 .as{margin-left:auto;font:400 10.5px var(--mono);color:var(--faint)}
body.workHomeOpen .whRoomHead .rh2 .gt{font:400 12.5px/1.5 var(--body);color:var(--muted);margin-top:7px}
/* The conversation starts below it, or the first message hides under the glass.
   ⛔ MARGIN, NOT PADDING — same fix, same reason as the band below: padding
   inside a scrolling box reserves space at the TOP OF THE CONTENT, so it holds
   only until the thread scrolls. Glass over a paragraph is not a soft edge, it
   is an unreadable paragraph. */
body.workHomeOpen:has(.whRoomHead) .msgs{margin-top:72px}
/* ⛔ THE BAND IS NOT A FIXED HEIGHT AND MUST NOT BE RESERVED AS ONE. The room
   header above is 72px because it is always the same three lines; the person's
   band grows when they open the apps strip or their profile, and a fixed
   reservation would put the first answer underneath it the moment they did.
   ⚡ So the height is MEASURED after every paint and written to --wh-band.
   ⚠ The fallback is deliberately generous: if the measurement has not landed
   yet, too much space is a gap and too little is text hidden behind glass. */
/* ⛔ AND IT IS RESERVED AS A MARGIN, NOT AS PADDING — the owner found the
   difference on 2026-08-30 and the sentence he used was "the upper header part
   of this central chat block covers it": his own question, the one he had just
   asked, was underneath the band.
   ⛔ PADDING RESERVES SPACE INSIDE A SCROLLING BOX, WHICH ONLY EVER HELPS AT
   SCROLL TOP. The band is opaque (`background:var(--bg)`), it is painted by a
   fixed overlay, and `.msgs` scrolls under it — so the moment the thread was
   long enough to scroll, the newest turns slid behind the band and the padding
   was three screens above, doing nothing. A conversation that hides the
   sentence you just typed is not a conversation.
   ⚡ A margin shrinks the SCROLL VIEWPORT instead, so the box begins below the
   band and nothing can pass under it at any scroll position. `margin:0 auto`
   still centres it — only the top is overridden.
   ⚠ `scroll-padding-top` is set as well: it is what keeps a programmatic
   scrollIntoView (the jump button, an anchored answer) from landing a message
   flush against the top edge. */
body.workHomeOpen:has(.whPBand) .msgs{margin-top:var(--wh-band,104px);
  scroll-padding-top:8px}
body.workHomeOpen:has(.whPBand) .thread{padding-top:0}

/* ── ours: a room is arranged by the person who works in it ───────────────── */
/* ⛔ THE DRAG FEEDBACK IS THE PROMISE. A row that lifts and a line that shows
   where it will land are what make a rail feel arrangeable; without them a
   drag is indistinguishable from a failed click. */
/* ⚡ SOMETHING IS WORKING IN THIS ROOM, RIGHT NOW. One animated mark beside the
   room, instead of a panel listing everything happening in every room — the
   owner's own suggestion, and the better one: a person scanning the rail wants
   to know WHERE, not WHAT.
   ⛔ It animates only while an agent is genuinely running against a goal this
      room holds. ⚠ And it respects reduced motion: an indicator nobody can
      look at is worse than a static dot.
   ⚠ NAMED `whBusy`, NOT `.spin` — os.css already owns that class, and the
     collision scanner caught it before it shipped. That check has now paid for
     itself twice; the first time was `.logo`, the wordmark, which put a
     company's tile in the middle of its own name. */
body.workHomeOpen .whAppNav .room .whBusy{margin-left:auto;flex:none;width:11px;height:11px;
  border-radius:50%;border:1.5px solid var(--line2);border-top-color:var(--mint);
  animation:whSpin 900ms linear infinite}
@keyframes whSpin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){
  body.workHomeOpen .whAppNav .room .whBusy{animation:none;border-color:var(--mint)}
}

/* ⛔ THE GRIP IS THE ONLY DRAGGABLE THING. A `draggable` button does not
   receive clicks in WebKit — the row highlighted on hover and did nothing when
   pressed, which reads as a broken handler and not as a drag attribute. */
body.workHomeOpen .whAppNav .room .grip{margin-left:6px;flex:none;cursor:grab;
  color:var(--faint);font-size:11px;line-height:1;opacity:0;transition:opacity .14s}
body.workHomeOpen .whAppNav .room:hover .grip,
body.workHomeOpen .whAppNav .room .grip:focus-visible{opacity:.65}
body.workHomeOpen .whAppNav .room .grip:hover{opacity:1;color:var(--ink)}
body.workHomeOpen .whAppNav .room .g+.grip{margin-left:6px}
body.workHomeOpen .whAppNav .room .grip:active{cursor:grabbing}
body.workHomeOpen .whAppNav .room.dragging{opacity:.45;cursor:grabbing}
body.workHomeOpen .whAppNav .room.dropbefore{box-shadow:inset 0 2px 0 var(--fill)}
/* ── a room's settings: a sheet over the room, not a fold in the rail ──────
   ⛔ THE RAIL IS A LIST OF ROOMS AND NOTHING ELSE (owner, 2026-09-08). The fold
      that used to live under every room row is gone: twelve rooms carried
      twelve `•••` marks, and opening one put a two-form settings page inside a
      262 px column. The settings did not disappear — they moved to the room's
      own header line, which already named every one of them.
   ⛔ NOTHING HERE IS SCOPED `.whAppNav` ANY MORE. That prefix is why the old
      rules existed at all; a copy of them under the rail would style a fold
      that no longer exists and hide the fact that it is gone. */
body.workHomeOpen .whRoomSet{position:fixed;inset:0;z-index:24;display:grid;place-items:center;
  padding:24px;background:rgba(24,20,34,.34);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
body.workHomeOpen .whRoomSetCard{width:min(560px,100%);max-height:min(80vh,720px);overflow:auto;
  background:var(--surf);border:1px solid var(--line2);border-radius:var(--r-l,20px);
  box-shadow:0 30px 70px -28px rgba(20,14,40,.6);padding:18px 20px 20px}
body.workHomeOpen .whRoomSetCard>header{display:flex;align-items:center;gap:10px;margin-bottom:12px}
body.workHomeOpen .whRoomSetCard>header h2{margin:0;flex:1;min-width:0;display:flex;align-items:center;gap:8px;
  font:600 17px/1.2 var(--disp);letter-spacing:-.015em;color:var(--ink)}
body.workHomeOpen .whRoomSetCard>header h2 .km{width:22px;height:22px;object-fit:contain;display:block}
body.workHomeOpen .whRoomSetX{flex:none;width:28px;height:28px;border-radius:999px;border:1px solid var(--line2);
  background:transparent;color:var(--muted);font:400 16px/1 var(--body);cursor:pointer}
body.workHomeOpen .whRoomSetX:hover{color:var(--ink);background:var(--surf2)}
/* two tabs, because the room answers two different questions and mixing them
   into one scroll is what made the fold feel like a page */
body.workHomeOpen .whRoomSetTabs{display:flex;gap:6px;margin-bottom:12px}
body.workHomeOpen .whRoomSetTabs button{padding:5px 12px;border-radius:999px;border:1px solid var(--line2);
  background:transparent;color:var(--muted);font:500 12.5px var(--body);cursor:pointer}
body.workHomeOpen .whRoomSetTabs button.on{background:var(--fill);color:var(--onfill);border-color:transparent}
body.workHomeOpen .whRoomSetCard p{font-size:12.5px;line-height:1.55;color:var(--muted);margin:0 0 10px}
body.workHomeOpen .whRoomSetCard textarea{width:100%;box-sizing:border-box;resize:vertical;
  padding:10px 12px;border-radius:var(--r-s);border:1px solid var(--line2);background:var(--surf2);
  color:var(--ink);font:400 13.5px/1.55 var(--body)}
body.workHomeOpen .whRoomSetCard textarea:focus{outline:none;border-color:var(--fill-2)}
/* the goals picker — a real list, because "which of eighty" is not a sentence */
body.workHomeOpen .whRoomSetCard .allrow{display:flex;align-items:center;gap:8px;margin:7px 0;
  font-size:13px;color:var(--ink);cursor:pointer}
body.workHomeOpen .whRoomSetCard .goalpick{display:grid;gap:2px;max-height:300px;overflow:auto;
  margin:10px 0 2px;padding:9px 11px;border:1px solid var(--line);border-radius:var(--r-s);background:var(--surf2)}
body.workHomeOpen .whRoomSetCard .goalpick label{display:grid;grid-template-columns:16px minmax(0,1fr);gap:9px;
  align-items:start;padding:4px 2px;font-size:13px;line-height:1.45;color:var(--muted);cursor:pointer}
body.workHomeOpen .whRoomSetCard .goalpick label:hover{color:var(--ink)}
body.workHomeOpen .whRoomSetCard .goalpick input{margin-top:3px}
/* ⛔ The picker is hidden when the room is wide — a list of eighty checkboxes
   under a radio that says "every goal" invites a person to tick one by accident
   and narrow a room they meant to leave alone. */
body.workHomeOpen .whRoomSetCard form:has(input[value="all"]:checked) .goalpick{display:none}
body.workHomeOpen .whRoomSetCard .scopeact{display:flex;align-items:center;gap:11px;margin-top:12px;flex-wrap:wrap}
body.workHomeOpen .whRoomSetCard .scopeact .pri{padding:7px 16px;border-radius:999px;background:var(--fill);
  color:var(--onfill);border:0;font:500 13px var(--body);cursor:pointer}
/* ⛔ The limit of the thing is said NEXT TO the control that sets it. A scope
   box with no note reads as a wall the platform enforces, and it is not one. */
body.workHomeOpen .whRoomSetCard .scopeact .fine{font:400 10.5px/1.45 var(--mono);color:var(--faint);flex:1;min-width:180px}
/* ── the room header's chips are controls, not facts ──────────────────────
   ⚡ The model chip was already a button; these are its neighbours and must
      read as the same kind of thing. A chip that opens something looks
      pressable; a fact stays a span. */
body.workHomeOpen .whRoomHead .rhBit{background:none;border:0;padding:0;font:inherit;color:inherit;
  cursor:pointer;border-bottom:1px solid transparent;transition:color .15s ease,border-color .15s ease}
body.workHomeOpen .whRoomHead .rhBit:hover,body.workHomeOpen .whRoomHead .rhBit:focus-visible{
  color:var(--ink);border-bottom-color:var(--line2);outline:none}
body.workHomeOpen .whRoomHead .rh2 .gt{background:none;border:0;padding:0;font:inherit;color:inherit;
  text-align:left;cursor:pointer;border-bottom:1px solid transparent;transition:color .15s ease,border-color .15s ease}
body.workHomeOpen .whRoomHead .rh2 .gt:hover,body.workHomeOpen .whRoomHead .rh2 .gt:focus-visible{
  color:var(--ink);border-bottom-color:var(--line2);outline:none}
@media (max-width:560px){
  body.workHomeOpen .whRoomSet{padding:0;place-items:end stretch}
  body.workHomeOpen .whRoomSetCard{width:100%;max-height:86vh;border-radius:20px 20px 0 0;border-bottom:0}
}

/* ⛔ AN ABSENCE IS RENDERED WHERE THE THING WOULD HAVE BEEN, never as a blank:
   a company whose apps we could not read must not look like a company with no
   apps. Same amber the rail uses for a lane that needs a person. */
body.workHomeOpen .whHome .absent{margin:10px 16px 14px;padding:9px 11px;border-radius:9px;
  background:rgba(251,191,36,.10);border:1px solid rgba(251,191,36,.26);
  font-size:11.5px;line-height:1.5;color:var(--muted)}
body.workHomeOpen .whHome .blk .absent:first-child{margin-top:14px}
body.workHomeOpen .whHome .rh2.nogoal .give:hover{background:var(--surf2)}
body.workHomeOpen .whHome .rh1 .as{font-variant-numeric:tabular-nums}
@media (max-width:860px){body.workHomeOpen .whHome{left:0}}

/* ══ GENERATED — node tools/scope-proto-css.mjs ═══════════════════════════ */
/* ── the plane · proto/ui.css:42–53 ────────────────────── */
body.workHomeOpen .whPlane::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:url(/art/os/bg-clay.webp) center/cover no-repeat;opacity:.80;
  filter:saturate(1.15) contrast(.98) brightness(1.5)}
body.workHomeOpen .whPlane::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(1250px 700px at 78% -20%,var(--glowA),transparent 60%),
             radial-gradient(900px 600px at 4% 106%,var(--glowB),transparent 62%),
             linear-gradient(180deg,rgba(17,23,38,.42),rgba(17,23,38,.72))}
:root[data-theme="light"] body.workHomeOpen .whPlane::before{background-image:url(/art/os/bg-clay.webp);opacity:.55;
  filter:grayscale(1) brightness(1.06) contrast(.96)}
:root[data-theme="light"] body.workHomeOpen .whPlane::after{
  background:radial-gradient(1250px 700px at 78% -20%,var(--glowA),transparent 60%),
             linear-gradient(180deg,rgba(246,247,251,.46),rgba(246,247,251,.66))}

/* ── the rail · proto/ui.css:81–111 ────────────────────── */
body.workHomeOpen .whAppNav{border-right:1px solid var(--line);background:var(--glass);backdrop-filter:blur(26px) saturate(1.3);overflow:auto;padding:10px 8px 12px;display:flex;flex-direction:column;gap:2px}
body.workHomeOpen .whAppNav .today{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:11px;border:1px solid var(--line);background:var(--surf);margin-bottom:10px}
body.workHomeOpen .whAppNav .today.on{border-color:var(--line2);background:var(--surf2)}
body.workHomeOpen .whAppNav .today .d{font:600 14px var(--disp)}
body.workHomeOpen .whAppNav .today .s{font-size:11.5px;color:var(--muted)}
body.workHomeOpen .whAppNav .today .n{margin-left:auto;font:500 11px var(--mono);color:var(--bg);background:var(--amber);border-radius:999px;padding:2px 7px}
body.workHomeOpen .whAppNav h4{font:500 10px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--faint);padding:14px 12px 7px;display:flex;justify-content:space-between}
body.workHomeOpen .whAppNav h4 .c{font:400 10px var(--mono);letter-spacing:0;text-transform:none}
body.workHomeOpen .whAppNav .sbj{display:flex;align-items:center;gap:10px;width:100%;padding:7px 11px;border-radius:10px;text-align:left;color:var(--ink);font-size:13.5px;position:relative}
body.workHomeOpen .whAppNav .sbj:hover{background:var(--surf)}
body.workHomeOpen .whAppNav .sbj.open{background:var(--surf)}
body.workHomeOpen .whAppNav .sbj .mk{width:23px;height:23px;border-radius:7px;display:grid;place-items:center;font:600 9.5px var(--disp);flex:none;background:var(--surf2);color:var(--muted);border:1px solid var(--line)}
body.workHomeOpen .whAppNav .sbj .mk.idea{border-style:dashed;background:transparent}
body.workHomeOpen .whAppNav .sbj .mk.own{background:var(--fill);color:var(--onfill);border-color:transparent}
body.workHomeOpen .whAppNav .sbj .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body.workHomeOpen .whAppNav .sbj .dot{width:6px;height:6px;border-radius:50%;background:var(--amber);margin-left:auto;flex:none}
body.workHomeOpen .whAppNav .sbj .ch{margin-left:auto;color:var(--faint);font-size:10px;transition:transform .18s}
body.workHomeOpen .whAppNav .sbj.open .ch{transform:rotate(90deg)}
body.workHomeOpen .whAppNav .rooms{display:flex;flex-direction:column;gap:1px;margin:2px 0 6px;padding-left:22px}
body.workHomeOpen .whAppNav .room{display:flex;align-items:center;gap:9px;padding:6px 11px;border-radius:9px;text-align:left;font-size:13px;color:var(--muted);width:100%}
body.workHomeOpen .whAppNav .room:hover{background:var(--surf);color:var(--ink)}
body.workHomeOpen .whAppNav .room.on{background:var(--surf2);color:var(--ink)}
body.workHomeOpen .whAppNav .room.on::before{content:'';position:absolute;left:8px;width:3px;height:16px;border-radius:2px;background:var(--fill)}
body.workHomeOpen .whAppNav .room{position:relative}
body.workHomeOpen .whAppNav .room .h{color:var(--faint);font:400 12px var(--mono);flex:none}
body.workHomeOpen .whAppNav .room .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
body.workHomeOpen .whAppNav .room .g{margin-left:auto;font:400 10px var(--mono);color:var(--faint);flex:none}
body.workHomeOpen .whAppNav .room .g.live{color:var(--mint)}
body.workHomeOpen .whAppNav .room .g.warn{color:var(--amber)}
body.workHomeOpen .whAppNav .add{padding:6px 12px;font-size:12px;color:var(--faint);text-align:left;border-radius:9px}
body.workHomeOpen .whAppNav .add:hover{color:var(--ink);background:var(--surf)}

/* ── the workplace row · proto/ui.css:294–301 ────────────────────── */
body.workHomeOpen .whAppNav .sbjrow{display:flex;align-items:center;gap:2px;border-radius:10px}
body.workHomeOpen .whAppNav .sbjrow:hover{background:var(--surf)}
body.workHomeOpen .whAppNav .sbjrow.here{background:var(--surf2)}
body.workHomeOpen .whAppNav .sbjrow .sbj{flex:1;min-width:0}
body.workHomeOpen .whAppNav .sbjrow .sbj:hover{background:transparent}
body.workHomeOpen .whAppNav .sbjrow .chv{width:22px;height:26px;color:var(--faint);font-size:10px;flex:none;border-radius:7px;transition:transform .18s}
body.workHomeOpen .whAppNav .sbjrow .chv:hover{color:var(--ink)}
body.workHomeOpen .whAppNav .sbjrow .chv.open{transform:rotate(90deg)}

/* ── entities in the rail · proto/ui.css:438–444 ────────────────────── */
body.workHomeOpen .whAppNav .sbjrow.me{margin-top:4px}
body.workHomeOpen .whAppNav .sbj .mk.person{background:var(--fill);color:var(--onfill);border-color:transparent;border-radius:50%}
body.workHomeOpen .whAppNav .sbj .mk.proj{border-style:dashed}
body.workHomeOpen .whAppNav .room .h{width:12px;text-align:center}
body.workHomeOpen .whAppNav .room.k-private .h{color:var(--ink);font-size:9px}
body.workHomeOpen .whAppNav .room.k-idea .h,body.workHomeOpen .whAppNav .room.k-project .h{color:var(--faint)}
body.workHomeOpen .whAppNav .room.k-private .nm{color:var(--muted)}

/* ── a company mark · proto/ui.css:560–561 ────────────────────── */
body.workHomeOpen .whAppNav .sbj .mk.mklogo{background:#fff;border-color:transparent;padding:2px;overflow:hidden}
body.workHomeOpen .whAppNav .sbj .mk img{width:100%;height:100%;object-fit:contain;display:block}

/* ── the room mark · proto/ui.css:576–577 ────────────────────── */
body.workHomeOpen .whAppNav .room .h{transition:color .16s}
body.workHomeOpen .whAppNav .room:hover .h,body.workHomeOpen .whAppNav .room.on .h{color:var(--ink)}

/* ── the content wrap · proto/ui.css:115–116 ────────────────────── */
body.workHomeOpen .whHome .wrap{padding:22px 34px 34px;display:flex;flex-direction:column;gap:18px;max-width:880px;width:100%;margin:0 auto}
body.workHomeOpen .whHome .wrap.wide{max-width:1060px}

/* ── the day · proto/ui.css:205–207 ────────────────────── */
body.workHomeOpen .whHome .day{display:flex;flex-direction:column;gap:16px}
body.workHomeOpen .whHome .day h1{font:600 27px/1.15 var(--disp);letter-spacing:-.02em}
body.workHomeOpen .whHome .day h1 small{display:block;font:400 13.5px/1.5 var(--body);color:var(--muted);margin-top:5px;letter-spacing:0}

/* ── the decision card · proto/ui.css:180–187 ────────────────────── */
body.workHomeOpen .whHome .ask{border-radius:var(--r);padding:15px 17px;background:var(--glass);backdrop-filter:blur(18px);border:1px solid var(--line2);box-shadow:var(--lift-2),inset 3px 0 0 var(--fill)}
body.workHomeOpen .whHome .ask .q{font:500 16px/1.4 var(--disp);color:var(--ink);margin-bottom:6px}
body.workHomeOpen .whHome .ask .w{font-size:13px;color:var(--muted);margin-bottom:13px}
body.workHomeOpen .whHome .ask .opts{display:flex;gap:8px;flex-wrap:wrap}
body.workHomeOpen .whHome .ask .opts button{padding:8px 14px;border-radius:999px;border:1px solid var(--line2);font-size:13px;color:var(--ink)}
body.workHomeOpen .whHome .ask .opts button:hover{background:var(--surf2)}
body.workHomeOpen .whHome .ask .opts button.pri{background:var(--fill);color:var(--onfill);border-color:transparent;font-weight:500}
body.workHomeOpen .whHome .ask .exp{margin-top:11px;font:400 10.5px var(--mono);color:var(--faint)}

/* ── a goal chip · proto/ui.css:496–512 ────────────────────── */
body.workHomeOpen .whHome .gchip{display:flex;align-items:center;gap:11px;text-align:left;padding:5px 11px 5px 5px;border-radius:999px;
  border:1px solid var(--line);background:var(--surf);transition:.16s;max-width:100%}
body.workHomeOpen .whHome .gchip:hover{border-color:var(--line2);background:var(--surf2)}
body.workHomeOpen .whHome .gchip .ring{position:relative;width:34px;height:34px;flex:none;display:block}
body.workHomeOpen .whHome .gchip .ring svg{width:100%;height:100%;transform:rotate(-90deg)}
body.workHomeOpen .whHome .gchip .ring .trk{fill:none;stroke:var(--surf2);stroke-width:3.5}
body.workHomeOpen .whHome .gchip .ring .prg{fill:none;stroke:var(--fill);stroke-width:3.5;stroke-linecap:round}
body.workHomeOpen .whHome .gchip .mk{position:absolute;inset:0;display:grid;place-items:center;font:600 11px var(--disp);color:var(--ink);letter-spacing:-.02em}
body.workHomeOpen .whHome .gchip .tx{display:block;min-width:0}
body.workHomeOpen .whHome .gchip .tx b{display:block;font:600 13px var(--disp);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.workHomeOpen .whHome .gchip .tx span{display:block;font:400 10.5px var(--mono);color:var(--faint);margin-top:2px}
body.workHomeOpen .whHome .gchip.big{padding:8px 16px 8px 8px;border-radius:18px}
body.workHomeOpen .whHome .gchip.big .ring{width:52px;height:52px}
body.workHomeOpen .whHome .gchip.big .ring .trk,body.workHomeOpen .whHome .gchip.big .ring .prg{stroke-width:3}
body.workHomeOpen .whHome .gchip.big .mk{font-size:15px}
body.workHomeOpen .whHome .gchip.big .tx b{font-size:15px}
body.workHomeOpen .whHome .rh2 .gchip{grid-column:1;justify-self:start;margin-bottom:10px}

/* ── a goal card · proto/ui.css:222–229 ────────────────────── */
body.workHomeOpen .whHome .gcard{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px;padding:13px 16px;border-top:1px solid var(--line);align-items:center;text-align:left;width:100%}
body.workHomeOpen .whHome .gcard:first-of-type{border-top:0}
body.workHomeOpen .whHome .gcard:hover{background:var(--surf)}
body.workHomeOpen .whHome .gcard .nm{font:500 13.5px var(--disp)}
body.workHomeOpen .whHome .gcard .s{font-size:12px;color:var(--muted);margin-top:3px}
body.workHomeOpen .whHome .gcard .mini{width:120px;height:4px;border-radius:99px;background:var(--surf2);position:relative;flex:none}
body.workHomeOpen .whHome .gcard .mini i{position:absolute;left:0;top:0;bottom:0;border-radius:99px;background:var(--fill);opacity:.85}
body.workHomeOpen .whHome .gcard .pc{font:500 11px var(--mono);color:var(--muted);text-align:right;margin-top:5px}

/* ── what happened · proto/ui.css:554–557 ────────────────────── */
body.workHomeOpen .whHome .ln.act{grid-template-columns:64px minmax(0,1fr) auto}
body.workHomeOpen .whHome .ln .ti{display:flex;align-items:center;gap:8px}
body.workHomeOpen .whHome .ln .ti img{width:24px;height:24px;object-fit:contain;flex:none;filter:saturate(.9)}
body.workHomeOpen .whHome .ln .ti i{font:400 10.5px var(--mono);font-style:normal;color:var(--faint)}

/* ── a block and its lines · proto/ui.css:208–221 ────────────────────── */
body.workHomeOpen .whHome .blk{border:1px solid var(--line);border-radius:var(--r);background:var(--glass);backdrop-filter:blur(22px) saturate(1.25);box-shadow:var(--lift);overflow:hidden}
body.workHomeOpen .whHome .blk>h3{font:500 10px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--faint);padding:13px 16px 12px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--line)}
body.workHomeOpen .whHome .blk>h3 .c{font:400 10px var(--mono);letter-spacing:0;text-transform:none}
body.workHomeOpen .whHome .ln{display:grid;grid-template-columns:54px minmax(0,1fr) auto;gap:13px;padding:11px 16px;border-top:1px solid var(--line);align-items:baseline;font-size:13.5px;text-align:left;width:100%}
body.workHomeOpen .whHome .ln:first-of-type{border-top:0}
body.workHomeOpen .whHome .ln:hover{background:var(--surf)}
body.workHomeOpen .whHome .ln .t{font:400 10.5px var(--mono);color:var(--faint)}
body.workHomeOpen .whHome .ln .s{font-size:12px;color:var(--muted);margin-top:3px}
body.workHomeOpen .whHome .ln .r{font:400 11px var(--mono);color:var(--faint);white-space:nowrap}
body.workHomeOpen .whHome .ln .r.w{color:var(--amber)}
body.workHomeOpen .whHome .ln .r.ok{color:var(--mint)}
body.workHomeOpen .whHome .ln .sub{display:inline-flex;align-items:center;gap:5px;font:400 10.5px var(--mono);color:var(--faint);border:1px solid var(--line);border-radius:5px;padding:1px 6px;margin-right:7px}
body.workHomeOpen .whHome .two{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:1240px){body.workHomeOpen .whHome .two{grid-template-columns:1fr}}

/* ── a goal row · proto/ui.css:311–331 ────────────────────── */
body.workHomeOpen .whHome .grow{display:grid;grid-template-columns:minmax(0,1fr) 252px 132px;gap:18px;padding:13px 16px;border-top:1px solid var(--line);align-items:center;text-align:left;width:100%}
body.workHomeOpen .whHome .grow:first-of-type{border-top:0}
body.workHomeOpen .whHome .grow:hover{background:var(--surf)}
body.workHomeOpen .whHome .grow .ttl{font:500 13.5px/1.4 var(--disp);color:var(--ink)}
body.workHomeOpen .whHome .grow .sub{font-size:12px;color:var(--muted);margin-top:4px;line-height:1.45}
body.workHomeOpen .whHome .grow .sub b{color:var(--ink);font-weight:500}
body.workHomeOpen .whHome .grow .mini{height:4px;border-radius:99px;background:var(--surf2);position:relative}
body.workHomeOpen .whHome .grow .mini i{position:absolute;left:0;top:0;bottom:0;border-radius:99px;background:var(--fill);opacity:.85}
body.workHomeOpen .whHome .grow .leg{display:flex;justify-content:space-between;gap:12px;font:400 10px var(--mono);color:var(--faint);margin-top:6px}
body.workHomeOpen .whHome .grow .leg span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:56%}
body.workHomeOpen .whHome .grow .leg span:last-child{text-align:right}
body.workHomeOpen .whHome .grow .gs{text-align:right}
body.workHomeOpen .whHome .grow .st{font:400 10.5px var(--mono);color:var(--muted)}
body.workHomeOpen .whHome .grow .st.w{color:var(--amber)} body.workHomeOpen .whHome .grow .st.ok{color:var(--mint)}
body.workHomeOpen .whHome .grow .car{font:500 11.5px var(--mono);color:var(--ink);margin-top:4px}
body.workHomeOpen .whHome .grow .as{font:400 10px var(--mono);color:var(--faint);margin-top:3px}
body.workHomeOpen .whHome .idleblk{border-color:rgba(251,191,36,.28)}
body.workHomeOpen .whHome .reached{opacity:.72}
body.workHomeOpen .whHome .reached .grow .car{color:var(--mint)}
body.workHomeOpen .whHome .idleblk .grow .car{color:var(--amber)}
body.workHomeOpen .whHome .ln.idle .s{color:var(--faint)}

/* ── the page header · proto/ui.css:340–366 ────────────────────── */
body.workHomeOpen .whHome .rhead{position:sticky;top:0;z-index:12;background:var(--glassT);backdrop-filter:blur(30px) saturate(1.35);
  border-bottom:1px solid var(--line);padding:13px 34px 15px;flex:none}
body.workHomeOpen .whHome .rh1{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--muted);margin-bottom:9px}
body.workHomeOpen .whHome .rh1 .crumb{color:var(--muted);border-radius:6px;padding:1px 3px}
body.workHomeOpen .whHome .rh1 .crumb:hover{color:var(--ink)}
body.workHomeOpen .whHome .rh1 .sep{color:var(--faint)}
body.workHomeOpen .whHome .rh1 .rm{color:var(--ink);font-weight:500}
body.workHomeOpen .whHome .rh1 .kind{font:400 10px var(--mono);color:var(--faint);border:1px solid var(--line);border-radius:5px;padding:1px 7px}
body.workHomeOpen .whHome .rh1 .as{margin-left:auto;font:400 10.5px var(--mono);color:var(--faint)}
body.workHomeOpen .whHome .rh2{display:grid;grid-template-columns:minmax(0,1fr) 304px;gap:30px;align-items:start}
body.workHomeOpen .whHome .rh2 .gt{font:500 17px/1.35 var(--disp);color:var(--ink);letter-spacing:-.01em}
body.workHomeOpen .whHome .rh2 .gap{grid-column:1;font-size:12.5px;color:var(--muted);margin-top:7px;line-height:1.5}
body.workHomeOpen .whHome .rh2 .gap em{font-style:normal;color:var(--ink);font-weight:500}
body.workHomeOpen .whHome .rh2 .meas{grid-column:2;grid-row:1/3;padding-top:3px}
body.workHomeOpen .whHome .rh2 .rule{position:relative;height:11px}
body.workHomeOpen .whHome .rh2 .tr{position:absolute;inset:5px 0;border-radius:99px;background:var(--surf2)}
body.workHomeOpen .whHome .rh2 .fl{position:absolute;top:5px;bottom:5px;left:0;border-radius:99px;background:var(--fill);opacity:.9}
body.workHomeOpen .whHome .rh2 .pin{position:absolute;top:-1px;width:12px;height:12px;border-radius:50%;background:var(--fill);
  border:3px solid var(--bg);transform:translateX(-50%);box-shadow:0 0 0 1px var(--line2)}
body.workHomeOpen .whHome .rh2 .legs{display:flex;justify-content:space-between;gap:10px;font:400 10.5px var(--mono);color:var(--faint);margin-top:7px}
body.workHomeOpen .whHome .rh2 .legs span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:58%}
body.workHomeOpen .whHome .rh2 .legs span:last-child{text-align:right;color:var(--muted)}
body.workHomeOpen .whHome .rh2.nogoal{display:flex;align-items:center;gap:14px}
body.workHomeOpen .whHome .rh2.nogoal .gt{font-weight:400;color:var(--muted);font-size:15px}
body.workHomeOpen .whHome .rh2.nogoal .give{margin-left:auto;font-size:12.5px;color:var(--ink);border:1px solid var(--line2);border-radius:999px;padding:5px 13px}
@media (max-width:1240px){body.workHomeOpen .whHome .rh2{grid-template-columns:1fr}body.workHomeOpen .whHome .rh2 .meas{grid-column:1;grid-row:auto}}
@media (max-width:840px){body.workHomeOpen .whHome .rhead{padding:11px 16px 13px}}

/* ── the apps grid · proto/ui.css:461–472 ────────────────────── */
/* apps grid on a workplace */
body.workHomeOpen .whHome .apps{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;padding:14px 16px}
body.workHomeOpen .whHome .appc{display:flex;flex-direction:column;gap:6px;padding:13px 14px;border:1px solid var(--line);border-radius:14px;text-align:left;background:var(--glass);backdrop-filter:blur(14px);box-shadow:var(--lift);transition:transform .18s cubic-bezier(.2,.8,.2,1),box-shadow .18s,border-color .18s}
body.workHomeOpen .whHome .appc:hover{border-color:var(--line2);transform:translateY(-3px);box-shadow:var(--lift-2)}
body.workHomeOpen .whHome .appc .ic{width:30px;height:30px;border-radius:9px;background:var(--fill);color:var(--onfill);display:grid;place-items:center;font:600 13px var(--disp)}
body.workHomeOpen .whHome .appc.ref .ic,body.workHomeOpen .whHome .appc.never .ic,body.workHomeOpen .whHome .appc.more .ic{background:transparent;border:1px dashed var(--line2);color:var(--muted)}
body.workHomeOpen .whHome .appc .nm{font:600 13px var(--disp);color:var(--ink);margin-top:2px}
body.workHomeOpen .whHome .appc .d{font-size:11.5px;color:var(--muted);line-height:1.4}
body.workHomeOpen .whHome .appc .st{font:400 10px var(--mono);color:var(--faint);margin-top:auto}
body.workHomeOpen .whHome .appc.on .st{color:var(--mint)}
body.workHomeOpen .whHome .appc.never .st{color:var(--amber)}
@media (max-width:1240px){body.workHomeOpen .whHome .apps{grid-template-columns:repeat(2,1fr)}}

/* ── generated icons · proto/ui.css:489–492 ────────────────────── */
/* ── generated icons ───────────────────────────────────────────────────── */
body.workHomeOpen .whHome .tool .ic img,body.workHomeOpen .whHome .appc .ic img,body.workHomeOpen .whHome .panel .ph .ic img,body.workHomeOpen .whHome .aroom .ah .ic img{width:100%;height:100%;object-fit:contain;display:block}
body.workHomeOpen .whHome .tool .ic:has(img),body.workHomeOpen .whHome .panel .ph .ic:has(img),body.workHomeOpen .whHome .aroom .ah .ic:has(img){background:transparent;border-color:transparent;padding:0}
body.workHomeOpen .whHome .appc .ic:has(img){background:transparent;border:0;width:38px;height:38px;margin:-2px 0 2px -3px}

/* ── micro-detail · proto/ui.css:566–573 ────────────────────── */
body.workHomeOpen .whHome .sbj,body.workHomeOpen .whHome .room,body.workHomeOpen .whHome .ln,body.workHomeOpen .whHome .tool,body.workHomeOpen .whHome .nx,body.workHomeOpen .whHome .appc,body.workHomeOpen .whHome .pg,body.workHomeOpen .whHome .tk,body.workHomeOpen .whHome .fl,body.workHomeOpen .whHome .pgrow,body.workHomeOpen .whHome .gchip{
  transition:background .16s,border-color .16s,transform .16s cubic-bezier(.2,.8,.2,1),box-shadow .16s}
body.workHomeOpen .whHome .room:hover,body.workHomeOpen .whHome .sbj:hover{transform:translateX(1px)}
body.workHomeOpen .whHome .tool:hover,body.workHomeOpen .whHome .nx:hover,body.workHomeOpen .whHome .pgrow:hover{transform:translateY(-1px)}
body.workHomeOpen .whHome .tool .ic,body.workHomeOpen .whHome .appc .ic{transition:transform .18s cubic-bezier(.2,.8,.2,1)}
body.workHomeOpen .whHome .tool:hover .ic{transform:scale(1.09) rotate(-3deg)}
body.workHomeOpen .whHome .appc:hover .ic{transform:scale(1.07) translateY(-1px)}
body.workHomeOpen .whHome .pg .pv{overflow:hidden}

/* ── the lit top edge · proto/ui.css:579–587 ────────────────────── */
/* a lit top edge is what makes glass read as glass */
body.workHomeOpen .whHome .blk,body.workHomeOpen .whHome .appc,body.workHomeOpen .whHome .tile,body.workHomeOpen .whHome .panel,body.workHomeOpen .whHome .aroom,body.workHomeOpen .whHome .composer .box,body.workHomeOpen .whHome .ask{position:relative}
body.workHomeOpen .whHome .blk::before,body.workHomeOpen .whHome .appc::before,body.workHomeOpen .whHome .tile::before,body.workHomeOpen .whHome .panel::before,body.workHomeOpen .whHome .aroom::before,body.workHomeOpen .whHome .composer .box::before{
  content:'';position:absolute;left:12px;right:12px;top:0;height:1px;pointer-events:none;z-index:2;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.16),transparent)}
:root[data-theme="light"] body.workHomeOpen .whHome .blk::before,:root[data-theme="light"] body.workHomeOpen .whHome .appc::before,:root[data-theme="light"] body.workHomeOpen .whHome .tile::before,:root[data-theme="light"] body.workHomeOpen .whHome .panel::before,:root[data-theme="light"] body.workHomeOpen .whHome .aroom::before,:root[data-theme="light"] body.workHomeOpen .whHome .composer .box::before{
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.92),transparent)}

/* ── the entrance · proto/ui.css:691–692 ────────────────────── */
body.workHomeOpen .whHome .fade{animation:whHomeIn .26s ease-out both}
@keyframes whHomeIn{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
/* ══ END GENERATED ════════════════════════════════════════════════════ */

/* ═══ THE GOALS PICKER — eighty-one goals become a map ═══════════════════════
   ⛔ THE COLOUR IS THE INDEX. A person finds Growth by its colour long before
      they read the word, which is the entire reason the categories exist; so
      the hue is bound to the category id and never to a count, a position or a
      state. A palette that reshuffles teaches nothing. */
body.workHomeOpen .whGoalPick{--cat:hsl(215 14% 62%);}
body.workHomeOpen .whGoalPick .cat-product  {--cat:hsl(268 62% 70%);}
body.workHomeOpen .whGoalPick .cat-tech     {--cat:hsl(199 72% 62%);}
body.workHomeOpen .whGoalPick .cat-growth   {--cat:hsl(152 52% 56%);}
body.workHomeOpen .whGoalPick .cat-marketing{--cat:hsl(024 82% 66%);}
body.workHomeOpen .whGoalPick .cat-ops      {--cat:hsl(212 34% 66%);}
body.workHomeOpen .whGoalPick .cat-money    {--cat:hsl(046 78% 62%);}
body.workHomeOpen .whGoalPick .cat-people   {--cat:hsl(330 58% 70%);}
body.workHomeOpen .whGoalPick .cat-risk     {--cat:hsl(002 68% 66%);}
/* ⚠ Unsorted is deliberately the GREY one, and it is not a colour in the
   palette: it must not look like a ninth category somebody chose. */
body.workHomeOpen .whGoalPick .cat-none     {--cat:hsl(215 10% 52%);}

body.workHomeOpen .whGoalPick .dot{display:inline-block;width:.5rem;height:.5rem;border-radius:2px;
  background:var(--cat);box-shadow:0 0 0 1px color-mix(in srgb,var(--cat) 40%,transparent);flex:0 0 auto;}

/* the bar: bulk acts on the left, the filter on the right */
body.workHomeOpen .whGoalPick .gbar{display:flex;gap:1rem;align-items:flex-start;flex-wrap:wrap;
  justify-content:space-between;margin:0 0 1.1rem;}
body.workHomeOpen .whGoalPick .gsel,
body.workHomeOpen .whGoalPick .gfils{display:flex;gap:.4rem;flex-wrap:wrap;}
body.workHomeOpen .whGoalPick .gbulk{font:inherit;font-size:.78rem;letter-spacing:.01em;cursor:pointer;
  padding:.34rem .68rem;border-radius:.5rem;color:var(--wh-dim);
  border:1px solid color-mix(in srgb,var(--wh-line) 80%,transparent);background:transparent;
  transition:color .16s,border-color .16s,background .16s;}
body.workHomeOpen .whGoalPick .gbulk:hover{color:var(--wh-ink);border-color:var(--wh-edge);
  background:color-mix(in srgb,var(--wh-ink) 5%,transparent);}
body.workHomeOpen .whGoalPick .gbulk[disabled]{opacity:.34;cursor:default;}
body.workHomeOpen .whGoalPick .gbulk.pri[aria-pressed="true"]{color:var(--wh-ink);
  border-color:var(--wh-edge);background:color-mix(in srgb,var(--wh-ink) 8%,transparent);}
body.workHomeOpen .whGoalPick .gfil{display:inline-flex;align-items:center;gap:.4rem;font:inherit;
  font-size:.78rem;cursor:pointer;padding:.32rem .6rem;border-radius:999px;color:var(--wh-dim);
  border:1px solid color-mix(in srgb,var(--wh-line) 70%,transparent);background:transparent;}
body.workHomeOpen .whGoalPick .gfil .n{opacity:.6;font-variant-numeric:tabular-nums;}
body.workHomeOpen .whGoalPick .gfil.all .dot{background:linear-gradient(135deg,
  hsl(268 62% 70%),hsl(199 72% 62%),hsl(152 52% 56%),hsl(024 82% 66%));}
body.workHomeOpen .whGoalPick .gfil:hover{color:var(--wh-ink);border-color:var(--wh-edge);}
body.workHomeOpen .whGoalPick .gfil.on{color:var(--wh-ink);
  border-color:color-mix(in srgb,var(--cat) 62%,transparent);
  background:color-mix(in srgb,var(--cat) 13%,transparent);}
body.workHomeOpen .whGoalPick .gnote{font-size:.82rem;color:var(--wh-dim);margin:-.4rem 0 1rem;}

/* a group carries its colour on the heading rule, not on every card */
/* ⚠ A group is a HEADING AND ITS CARDS — not a panel. The inherited .blk box
   drew a full-width surface around each one, so a group holding a single goal
   printed a large empty rectangle; with eight groups the screen read as mostly
   nothing. */
body.workHomeOpen .whGoalPick .gblk{margin:0 0 1.6rem;}
body.workHomeOpen .whGoalPick .gblk h3{display:flex;align-items:center;gap:.5rem;margin:0 0 .7rem;
  font:500 10px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--faint);}
body.workHomeOpen .whGoalPick .gblk h3 .c{font:400 10px var(--mono);letter-spacing:0;text-transform:none;opacity:.7;}
body.workHomeOpen .whGoalPick .gblk h3 .gbulk{margin-left:auto;}
body.workHomeOpen .whGoalPick .gblk h3::after{content:'';flex:0 0 2.2rem;height:1px;order:-1;
  background:linear-gradient(90deg,var(--cat),transparent);}
body.workHomeOpen .whGoalPick .gblk .s{font-size:.8rem;color:var(--wh-dim);margin:-.3rem 0 .7rem;max-width:56ch;}

/* the card: the pick is the body, reading is its own corner button */
body.workHomeOpen .whGoalPick .gcard{position:relative;display:flex;flex-direction:column;
  border-left:2px solid color-mix(in srgb,var(--cat) 66%,transparent);}
body.workHomeOpen .whGoalPick .gcard .gpick{all:unset;display:flex;flex-direction:column;gap:.34rem;
  cursor:pointer;padding:.85rem .9rem .6rem;min-height:5.4rem;}
body.workHomeOpen .whGoalPick .gcard .gpick .ic{font-variant-numeric:tabular-nums;color:var(--cat);
  font-size:.82rem;letter-spacing:.02em;}
/* ⛔ THE CATEGORY SHARES A ROW WITH THE STATE, it does not get its own. Its own
   row cost every card an extra line of height for two words — over eighty
   cards that is a screen and a half of scrolling bought with nothing. */
body.workHomeOpen .whGoalPick .gcard .gpick{padding-bottom:1.55rem;}
body.workHomeOpen .whGoalPick .gcard .gcat{position:absolute;right:.85rem;bottom:.62rem;
  display:flex;align-items:center;gap:.34rem;font-size:.68rem;color:var(--wh-dim);letter-spacing:.02em;}
body.workHomeOpen .whGoalPick .gcard .gpick .st{position:absolute;left:.9rem;bottom:.62rem;}
body.workHomeOpen .whGoalPick .gcard .gopen{position:absolute;top:.5rem;right:.5rem;width:1.5rem;height:1.5rem;
  display:grid;place-items:center;border-radius:.4rem;border:1px solid transparent;background:transparent;
  color:var(--wh-dim);font-size:.95rem;line-height:1;cursor:pointer;opacity:0;transition:opacity .16s,color .16s;}
body.workHomeOpen .whGoalPick .gcard:hover .gopen,
body.workHomeOpen .whGoalPick .gcard .gopen:focus-visible{opacity:1;}
body.workHomeOpen .whGoalPick .gcard .gopen:hover{color:var(--wh-ink);border-color:var(--wh-edge);}
body.workHomeOpen .whGoalPick .gcard.on{background:color-mix(in srgb,var(--cat) 9%,transparent);
  border-left-color:var(--cat);}

/* ⚡ THE DOCK'S SECTION CONTROL — a setting next to the count it changes,
   instead of a full-width row under it. */
body.os.inthread .osSec h4{display:flex;align-items:center;gap:.3rem;}
body.os.inthread .osSec h4 .osTog{flex:1 1 auto;min-width:0;}
body.os.inthread .osSecAct{flex:0 0 auto;width:1.4rem;height:1.4rem;display:grid;place-items:center;
  border:1px solid transparent;border-radius:.35rem;background:transparent;cursor:pointer;
  color:var(--os-dim,#7c8798);font-size:.78rem;line-height:1;opacity:.55;transition:opacity .16s,color .16s;}
body.os.inthread .osSec:hover .osSecAct,
body.os.inthread .osSecAct:focus-visible{opacity:1;}
body.os.inthread .osSecAct:hover{color:var(--os-ink,#e8edf5);border-color:var(--os-edge,#2a3342);}

/* the category chip is a CONTROL, and the palette belongs to one card */
body.workHomeOpen .whGoalPick .gcard .gcat{border:0;cursor:pointer;font:inherit;font-size:.68rem;
  padding:.1rem .28rem;border-radius:.3rem;background:transparent;transition:color .16s,background .16s;}
body.workHomeOpen .whGoalPick .gcard .gcat:hover,
body.workHomeOpen .whGoalPick .gcard .gcat.open{color:var(--wh-ink);
  background:color-mix(in srgb,var(--wh-ink) 8%,transparent);}
/* ⛔ THE PALETTE MUST NOT COVER THE GOAL IT IS SORTING. Laid over the card, it
   hid the title — so the one question the person is answering ("what kind of
   work is THIS?") was the thing taken off screen to answer it. It hangs below
   the card instead, which needs the card's own overflow opened. */
body.workHomeOpen .whGoalPick .gcard{overflow:visible;}
body.workHomeOpen .whGoalPick .apps,
body.workHomeOpen .whGoalPick .gblk,
body.workHomeOpen .whGoalPick .wrap{overflow:visible;}
/* ⛔ A z-index ON THE PALETTE IS NOT ENOUGH. Every card is `position:relative`
   with no z-index of its own, so the NEXT group's cards paint after it in DOM
   order and covered the palette's last row — "Nesakārtoti", the way back from a
   wrong sort. It looked like a clipping bug and was a paint-order one; the
   ancestor has to be raised, not the popover. */
body.workHomeOpen .whGoalPick .gblk:has(.gpal){position:relative;z-index:6;}
body.workHomeOpen .whGoalPick .gcard:has(.gpal){z-index:6;}
body.workHomeOpen .whGoalPick .gpal{position:absolute;top:calc(100% - .35rem);left:.35rem;right:.35rem;
  bottom:auto;z-index:5;
  display:grid;grid-template-columns:1fr 1fr;gap:.16rem;padding:.32rem;border-radius:.5rem;
  border:1px solid var(--wh-edge);background:var(--wh-sheet,rgba(18,22,30,.97));
  box-shadow:0 12px 34px rgba(0,0,0,.42);}
body.workHomeOpen .whGoalPick .gpc{display:flex;align-items:center;gap:.32rem;font:inherit;
  font-size:.66rem;cursor:pointer;padding:.24rem .3rem;border-radius:.32rem;border:1px solid transparent;
  background:transparent;color:var(--wh-dim);text-align:left;}
body.workHomeOpen .whGoalPick .gpc:hover{color:var(--wh-ink);
  background:color-mix(in srgb,var(--cat) 16%,transparent);}
body.workHomeOpen .whGoalPick .gpc.on{color:var(--wh-ink);
  border-color:color-mix(in srgb,var(--cat) 60%,transparent);}
body.workHomeOpen .whGoalPick .gpc.cat-none{grid-column:1 / -1;justify-content:center;
  border-top:1px solid var(--wh-line);border-radius:0 0 .32rem .32rem;margin-top:.14rem;padding-top:.3rem;}

/* ═══ WHERE THE ROOM'S COMPOSER SITS ═════════════════════════════════════════
   ⛔ THREE ATTEMPTS AT THIS RULE BROKE THE COMPOSER THREE DIFFERENT WAYS, and the
      cause each time was the same: `.composer` is styled in THREE places (the
      page's own 880px rule, the shell's `--wh-chat` rule in work-home.js, and
      here), and a fourth width on top of those interacts with all of them. The
      last version set width:auto here while the shell's rule still said
      width:min(var(--wh-chat),100%) — inside a fixed box whose width was already
      the difference of the two rails. The result was a column one character
      wide, and it only showed at some viewport widths.
   ⚡ SO THIS RULE SETS NO WIDTH AT ALL. It does exactly one thing: pin the
      composer to the bottom of the room's column. Its width is whatever the two
      rules that already own it say — and `all:revert` on width/max-width makes
      sure nothing here argues with them.
   ⛔ NOT position:fixed either. Fixed took it out of the thread's flow, which is
      what let a stale width rule size it against the viewport instead of its
      column. `sticky` keeps it in the column it was born in. */
body.workRoomSay .composer{position:sticky;bottom:0;z-index:12;
  width:revert;max-width:revert;margin-left:auto;margin-right:auto;
  padding:.55rem 1.1rem 1rem;pointer-events:auto;
  background:linear-gradient(180deg,transparent,rgba(8,11,17,.30) 45%,rgba(8,11,17,.48));}
:root[data-theme="light"] body.workRoomSay .composer{
  background:linear-gradient(180deg,transparent,rgba(246,246,249,.42) 45%,rgba(246,246,249,.70));}
body.workRoomSay .tfoot{display:none;}

/* ═══ THE LIGHT PLANE IS A TEXTURE, NOT AN OBJECT ════════════════════════════
   ⛔ In light theme the plane rendered `bg-light.webp` at .55 with only a
      grayscale filter, so a large rounded 3D form sat in the middle of the
      screen with hard edges — a white pillow behind the interface rather than a
      surface the interface sits on. The owner: "on one of the versions we had a
      nice background image that did blend in a superb way." Measured against
      the dark plane, which does blend: dark carries a .72 linear wash over the
      photograph and the form dissolves; light carried .44–.74 over an image
      twice as present, and the form survived.
   ⚡ THE FIX IS EXPOSURE, NOT A NEW PICTURE. The same file, far quieter and
      blurred past the point where its edges read as a shape, under a heavier
      wash. ⛔ Not edited into the generated paste block above — that block is
      re-emitted from proto/ui.css on every deploy and a hand edit there is
      reported as drift and overwritten.
   ⚠ The dark plane is deliberately untouched: it already blends, and the
     concept's own values are what make it do so. */
/* ⚠ `!important` on the three properties that MUST win. The generated block
   sets opacity/filter on the same selector, and line ~609 sets filter again for
   the --wh-lift knob; the cascade between the three depends on source order
   inside a file that is partly regenerated on every deploy. A declaration that
   wins by position in a file whose positions move is a declaration that will
   stop winning without anyone editing it. */
:root[data-theme="light"] body.workHomeOpen .whPlane::before{
  opacity:.16!important;
  filter:grayscale(1) brightness(1.08) contrast(.9) blur(2px)!important;
  transform:scale(1.03);}
:root[data-theme="light"] body.workHomeOpen .whPlane::after{
  background:radial-gradient(1250px 700px at 78% -20%,var(--glowA),transparent 62%),
             radial-gradient(900px 600px at 4% 106%,var(--glowB),transparent 64%),
             linear-gradient(180deg,rgba(246,247,251,.72),rgba(246,247,251,.90));}
/* …and the same for the system default, which stamps no data-theme at all. */
@media (prefers-color-scheme:light){
  :root:not([data-theme="dark"]) body.workHomeOpen .whPlane::before{
    opacity:.16!important;
    filter:grayscale(1) brightness(1.08) contrast(.9) blur(2px)!important;
    transform:scale(1.03);}
  :root:not([data-theme="dark"]) body.workHomeOpen .whPlane::after{
    background:radial-gradient(1250px 700px at 78% -20%,var(--glowA),transparent 62%),
               radial-gradient(900px 600px at 4% 106%,var(--glowB),transparent 64%),
               linear-gradient(180deg,rgba(246,247,251,.72),rgba(246,247,251,.90));}
}

/* ═══ WAITING, DRAWN AS WAITING ══════════════════════════════════════════════
   ⛔ The dock used to fall through to seven generic tools while the ledger was
      still being read, so on every reload the owner watched a placeholder
      company turn into his own. `unmeasured` is a state and its honest drawing
      is a WAIT — never a confident wrong list that happens to be replaced. */
body.os.inthread .osWait{display:flex;flex-direction:column;gap:8px;padding:4px 0 2px;position:relative}
body.os.inthread .osWaitMk{position:absolute;right:2px;top:-2px;width:26px;height:26px;
  object-fit:contain;opacity:.9;animation:osWaitFloat 2.4s ease-in-out infinite alternate}
@keyframes osWaitFloat{from{transform:translateY(1px) rotate(-4deg)}to{transform:translateY(-3px) rotate(4deg)}}
body.os.inthread .osWaitRow{display:block;height:30px;border-radius:9px;overflow:hidden;
  background:color-mix(in srgb,currentColor 6%,transparent)}
body.os.inthread .osWaitRow i{display:block;height:100%;width:100%;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,currentColor 9%,transparent),transparent);
  animation:osShimmer 1.35s ease-in-out infinite}
body.os.inthread .osWaitRow:nth-child(3) i{animation-delay:.12s}
body.os.inthread .osWaitRow:nth-child(4) i{animation-delay:.24s}
body.os.inthread .osWaitRow:nth-child(5) i{animation-delay:.36s}
@keyframes osShimmer{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
/* ⚠ Motion is a preference, not a decoration: a shimmer that cannot be turned
   off is one more thing moving on a screen somebody is trying to read. */
@media (prefers-reduced-motion:reduce){
  body.os.inthread .osWaitRow i,body.os.inthread .osWaitMk{animation:none}
  body.workHomeOpen .whLoading img{animation:none}
}


/* ═══ TWO REGRESSIONS THIS SESSION CAUSED, BOTH MEASURED ═════════════════════

   1 · THE RAILS WERE RESERVED TWICE. `body.workHomeOpen .thread` already pads
   --wh-nav + --wh-dock (272 + 324), so the composer's `width:100%` is 100% of a
   box that is ALREADY inside the rails. It then applied its own
   `padding-left:286px; padding-right:348px` on top — 634px more — and at 1500px
   the content box came to 270px, of which `.cwrap` got 150 and the textarea 12.
   That is the column one character wide, in three screenshots.
   ⛔ The rail padding belongs to whichever box is outermost, and inside the
      shell that is the thread. Here it is zero. */
/* ⚠ `body.os.inthread.workHomeOpen` — FOUR classes, because the rules being
   overridden are `body.os.inthread …` at three classes and a two-class selector
   loses to them silently. The first version of this fix used
   `body.workHomeOpen` and changed nothing at all; the measurement said so. */
body.os.inthread.workHomeOpen .composer,
body.os.inthread.workHomeOpen .msgs,
body.os.inthread.workHomeOpen .t-head{padding-left:24px;padding-right:24px}
@media (min-width:1180px){
  body.os.inthread.workHomeOpen .composer,
  body.os.inthread.workHomeOpen .msgs,
  body.os.inthread.workHomeOpen .t-head{padding-left:24px;padding-right:24px}
}

/* 2 · THE PLANE'S WASH WAS PAINTING OVER THE CONVERSATION. The plane lives
   inside the shell (z-index 9) and the thread is z-index 5, so the light
   theme's wash — which I raised to .72/.90 to stop the background reading as a
   white 3D object — covered every answer, every chip and the composer at about
   20% contrast. Both changes were right on their own; together they hid the
   product. ⛔ The conversation is the content and belongs ABOVE the chrome's
   backdrop; the rail and dock keep their own higher layers, and the thread is
   transparent under workHomeOpen so nothing of theirs is covered. */
/* ⛔ RAISING THE THREAD ABOVE THE SHELL WAS WRONG AND IT GREYED THE RAIL.
   `.workHomeView` has z-index 9, which makes it a STACKING CONTEXT: its
   children cannot escape it, so `.whAppNav{z-index:12}` still painted at 9 —
   below a thread at 10 — and the thread's own surface covered the rail. A
   z-index on a child of a stacking context is a promise the parent does not
   keep.
   ⚡ THE REAL CAUSE WAS NEVER THE LAYERING: it was that I raised the light
      plane's wash to .72/.90 to stop the background reading as a white 3D
      object, and that wash is what washed the conversation out. The image
      opacity is what kills the blob (.16); the wash only has to keep contrast
      off the picture. Tuned back to where the thread stays readable, with the
      layering left exactly as the concept had it. */
:root[data-theme="light"] body.workHomeOpen .whPlane::after,
:root:not([data-theme="dark"]) body.workHomeOpen .whPlane::after{
  background:radial-gradient(1100px 650px at 82% -12%,rgba(139,110,255,.18),transparent 64%),
             radial-gradient(850px 560px at 3% 103%,rgba(34,211,238,.13),transparent 66%),
             linear-gradient(180deg,rgba(249,250,255,.22),rgba(247,249,255,.50));}

/* ═══ THE ROOM'S HEADER — the room, not the last thing said in it ════════════
   ⛔ It used to carry the conversation's title, so `mana telpa` wore "Baltu Koks
      — kā lapa nes pieprasījumus" across its top: a private room labelled with
      whatever was last discussed in it. A place named after its most recent
      sentence is not a place. */
body.workHomeOpen .whRoomHead .rh1 .sp{flex:1}
body.workHomeOpen .whRoomHead .rshare{font:inherit;font-size:11.5px;letter-spacing:.01em;
  color:var(--muted);background:none;cursor:pointer;padding:.24rem .7rem;border-radius:999px;
  border:1px solid color-mix(in srgb,var(--line) 90%,transparent);transition:color .16s,border-color .16s}
body.workHomeOpen .whRoomHead .rshare:hover{color:var(--ink);border-color:var(--line2)}
body.workHomeOpen .whRoomHead .rh2 .gt.dim{opacity:.62}
/* the counted strip — it COUNTS, it never lists. A list of lanes here is the
   dock's job, and two panels answering one question is what the dock already
   paid for once. */
body.workHomeOpen .whRoomHead .rh3{display:flex;flex-wrap:wrap;gap:.1rem .95rem;margin-top:.34rem;
  font-size:11px;letter-spacing:.02em;color:var(--faint)}
body.workHomeOpen .whRoomHead .rh3 span{display:inline-flex;align-items:center;gap:.34rem}
body.workHomeOpen .whRoomHead .rh3 span+span::before{content:'·';opacity:.5;margin-right:.34rem}
/* ⚡ THE ROOM'S BRAIN CHIP (2026-08-30) — a control living among the room's
   facts. Same size and register as the `.rh3` bits, but a real button. */
body.workHomeOpen .whRoomHead .rh3 .rh-model{display:inline-flex;align-items:center;gap:.4rem;
  border:0;background:none;cursor:pointer;font:inherit;color:var(--faint);
  border-radius:6px;padding:1px 7px;margin-left:.4rem}
body.workHomeOpen .whRoomHead .rh3 .rh-model:hover{color:var(--ink);background:var(--surf2)}
body.workHomeOpen .whRoomHead .rh3 .rh-model .dot{width:6px;height:6px;border-radius:50%;
  background:var(--violet);display:inline-block}
body.workHomeOpen .whRoomHead .rh3 .rh-model .dot.off{background:var(--faint);opacity:.5}
/* The picker itself — a small menu under the header, same glass as the header. */
body.workHomeOpen .whModelPick{position:absolute;top:100%;right:34px;z-index:3;min-width:240px;
  margin-top:6px;padding:6px;border-radius:12px;border:1px solid var(--line);
  background:var(--glassT);backdrop-filter:blur(30px) saturate(1.35);
  box-shadow:0 18px 50px -18px rgba(0,0,0,.5);display:flex;flex-direction:column;gap:2px}
body.workHomeOpen .whModelPick button{display:flex;flex-direction:column;gap:2px;text-align:left;
  border:0;background:none;cursor:pointer;border-radius:8px;padding:7px 10px;font:inherit}
body.workHomeOpen .whModelPick button:hover:not(:disabled){background:var(--surf2)}
body.workHomeOpen .whModelPick button:disabled{opacity:.45;cursor:default}
body.workHomeOpen .whModelPick button.on{background:color-mix(in srgb,var(--violet) 12%,transparent)}
body.workHomeOpen .whModelPick button .nm{font-size:12.5px;font-weight:550;color:var(--ink)}
body.workHomeOpen .whModelPick button .nm em{font-style:normal;font-weight:400;font-size:10.5px;
  color:var(--violet);margin-left:.4rem}
body.workHomeOpen .whModelPick button .why{font-size:10.5px;color:var(--faint)}
/* ⚡ The measured caveat (models.mjs, 2026-09-10). Dimmer than the note and
   never hidden: a person picking a subscription CLI lane must read WHY it may
   refuse before they pick it, not after. */
body.workHomeOpen .whModelPick button .cav{font-size:10px;line-height:1.35;color:var(--faint);opacity:.85;
  border-left:2px solid color-mix(in srgb,var(--violet) 40%,transparent);padding-left:6px;margin-top:2px}
body.workHomeOpen .whModelPick button.sub .nm::after{content:'CLI';font-size:8.5px;font-weight:600;
  letter-spacing:.06em;margin-left:6px;padding:1px 4px;border-radius:4px;vertical-align:1px;
  background:color-mix(in srgb,var(--ink) 8%,transparent);color:var(--faint)}
@media(max-width:860px){body.workHomeOpen .whModelPick{right:16px}}


/* ⛔ AND THE PAGE'S TITLE BAR STANDS DOWN IN A ROOM. Two headers, one above the
   other, one naming the place and one naming the last topic, is the interface
   disagreeing with itself in the space of two lines. The room's header is the
   header here; the page keeps its own everywhere else. */
body.workRoomSay #thead,
body.workRoomSay #shareBtn{display:none!important}


/* ⛔ AND THE PAGE'S TITLE BAR LEAVES NO EMPTY STRIP BEHIND IT. Hiding #thead
   and #shareBtn inside a room left `.t-head` itself standing — its own padding
   and its bottom border with nothing in them, which is the band of dead space
   under the header. In a room the room's header IS the header; the bar goes
   entirely. */
body.workRoomSay .t-head{display:none!important}
/* ⛔ AND THE SPACE RESERVED FOR IT GOES WITH IT. `body.os.inthread .thread`
   pads 54px at the top to make room for `.t-head`; hiding the bar without
   dropping its reservation leaves 54px of empty page between the room's header
   and the first answer — a band that appeared the moment the room header
   replaced the topic bar, and that nothing on screen explains.
   ⚠ `.msgs` keeps ITS 72px: that one is reserved for `.whRoomHead`, which is
     still there. Two reservations, two different elements — only the one whose
     element is gone comes off. */
body.workRoomSay .thread{padding-top:0}


/* ⛔ AND THE THREE SURFACES UNDER THE BAR START LEVEL WITH EACH OTHER. The rail
   pads 10px at the top, the room header pads its own, and the dock pads its own
   — so even with the 6px offset gone, the first thing in each column sat at a
   different height and the eye read the difference as a gap under the header.
   ⚡ One number for all three, from the same token the bar is measured by. */
body.workHomeOpen .whAppNav{padding-top:12px}
body.workHomeOpen .whRoomHead{padding-top:12px}
body.os.inthread .osDock{padding-top:12px}


/* ⚡ THE BRAIN CHIP on an answer's meta row (owner, 2026-09-10) — which model
   wrote this paragraph. Quiet by default: it is a receipt, not a badge, and it
   must never outweigh the answer above it. */
.m-orc .meta .brainChip{display:inline-flex;align-items:center;gap:4px;font-size:10px;line-height:1;
  padding:2px 6px;border-radius:999px;color:var(--faint);
  background:color-mix(in srgb,var(--ink) 6%,transparent);
  border:1px solid color-mix(in srgb,var(--ink) 10%,transparent);cursor:default}
.m-orc .meta .brainChip.fast{border-style:dashed}
