/* ============================================================================
   ViryaCORE — the design system.
   Built from the approved direction, not adapted from anything. The old ANSR
   stylesheets (app.css, console.css, admin.css, ops-design.css, tokens.css) were
   thrown away; nothing here inherits from them.

   THE IDEA. An autonomy sensor housing is white and smooth with a single soft
   light turning inside it. So: white ground, enormous type, generous air, and
   the rotor as the only colour — ambient and blurred behind the page, or a thin
   live edge on a card. Never a filled panel. Never a background.

   Navigation is a floating capsule bar. Not a top tab strip, not a side rail.

   Part 2 at the bottom re-cuts the legacy class names the imported pages still
   use (.wrap, .tabs, .section, .btn, .chip, .flow-*, .kpi …) into this language,
   so no interior renders naked while it waits to be rebuilt properly.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens -- */
:root{
  --w:#FFFFFF;
  --mist:#F3F6F4;
  --fog:#E8EDEA;
  --line:rgba(16,19,18,.14);
  --line-2:rgba(16,19,18,.24);
  --ink:#0B0E0D;
  /* The greys, darkened twice. First pass fixed legibility — --ink-3 was 2.71:1
     against white, under the 4.5:1 ordinary text needs, and it carries every
     caption, muted line and table sub-label in the product. Second pass took
     each one a further shade down because they still read as faint on screen:
     --ink-2 9.03 → 10.99, --ink-3 4.92 → 6.32, --ink-4 3.13 → 3.92 (still
     decorative-only; never put sentences in it).
     The BORDERS went with them — an outline at .09 alpha on white is a hint of
     a line rather than a line. .09 → .14, and --line-2 .16 → .24.
     THIRD PASS, 4 Sep 2026 — Asa again: "very light i can't really read".
     Measured this time rather than eyeballed, and against the WORST ground a
     grey actually sits on (#EFEEE7, the Purple Orange paper) rather than white,
     which flatters by ~1.1x:

       --ink-2  9.45 -> 11.44
       --ink-3  5.43 ->  8.61
       --ink-4  3.37 ->  7.71   (it was never decorative-only in practice —
                                 it carried eight captions in Admin)

     The floor is now 7:1 (AAA), not 4.5. AA is a legal minimum; these boards
     are read all day. No grey goes into this file again without a computed
     ratio against #EFEEE7. */
  --ink-2:#2A312F;
  --ink-3:#3C4442;

  --red:#C02424;    --red-ink:#A81C20;
  --orange:#D8780C;
  --yellow:#FCD800; --yellow-ink:#7A6300;
  --green:#6CB43C;  --green-ink:#3B6E1E;
  /* --green-deep and --ink-4 were USED (bar fills in Signals, eight captions in
     Admin) but never DEFINED. An undefined custom property is not a fallback to
     something sensible — the whole declaration is invalid, so every bar fill was
     painting transparent and reading as an empty track. Define them here once. */
  --green-deep:#4E8F28;              /* solid fill weight — deeper than --green */
  --ink-4:#434B49;                   /* was #78837F / 3.37:1 — see the note above */

  /* chart palette — the brand sweep, taken apart into discrete series colours so
     a donut or a stacked bar stays on-brand without inventing new hues */
  --c1:#6CB43C; --c2:#0B0E0D; --c3:#D8780C; --c4:#C02424;
  --c5:#3B6E1E; --c6:#93A09B; --c7:#FCD800; --c8:#5A6663;

  --sweep:linear-gradient(115deg,#C02424,#D8780C 28%,#FCD800 56%,#6CB43C 100%);
  --sweep-conic:conic-gradient(from 210deg,#C02424,#D8780C 22%,#FCD800 46%,#6CB43C 72%,#C02424);

  --disp:"Archivo Expanded","Archivo","Helvetica Neue",system-ui,sans-serif;
  --body:"Inter",-apple-system,"Segoe UI",system-ui,sans-serif;

  --r:14px;      /* cards — soft but not bulbous */
  --r-sm:9px;
  --r-pill:100px;

  --shadow:0 2px 6px rgba(11,14,13,.03), 0 24px 60px -34px rgba(11,14,13,.5);
  --shadow-lift:0 40px 70px -46px rgba(11,14,13,.6);
  --ease:cubic-bezier(.2,.7,.3,1);
  --t:.35s var(--ease);
  --bar-h:92px;

  /* ---- compatibility aliases ---------------------------------------------
     Screens built while this file carried a different token set still ask for
     these. Restoring Virya's sheet removed the originals, and an undefined
     custom property does NOT fall back to something sensible — the whole
     declaration is invalid, so the rule simply does not apply. That is the exact
     failure this file warns about a few lines above, and it is silent: no error,
     no console warning, just a label that is suddenly the wrong face.
     Mapped onto Virya's own tokens rather than reintroducing a parallel set. */
  --font-label:var(--body);
  --font-text:var(--body);
  --font-display:var(--disp);
  --line-soft:rgba(16,19,18,.08);
  --track-md:.13em;
  --pearl:#FBF9F6;
}

/* ------------------------------------------------------------------ base -- */
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0; background:#FBF9F6; color:var(--ink);   /* pearl, not white */
  font-family:var(--body); font-weight:400; font-size:14.5px; line-height:1.5;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
img,svg,video,table{max-width:100%}
a{color:var(--green-ink); text-decoration:none}
::selection{background:rgba(108,180,60,.22)}
:focus-visible{outline:2px solid var(--green); outline-offset:3px; border-radius:6px}

/* the ambient aura — the rotor as light. Fixed: the page moves, the light does not. */
/* The ground light. This used to be three <b> elements injected into the body by
   JavaScript AFTER the page had already painted — so on every single navigation
   the page rendered white and the coloured wash arrived a frame later. That late
   arrival is a flash, and it happened on all five pages.

   It is pure decoration with no markup meaning, so it belongs in CSS on the body
   itself: painted in the very first frame, present in the view-transition
   snapshot, and impossible for a page to forget to include. */
/* ---- the ground: pearl ------------------------------------------------------
   THE ONLY DEPARTURE FROM VIRYA'S SHEET. Everything else in this file is Virya's
   verbatim — the type, the greys, the spacing, the radii, the shadows, the
   palette — because it is known good and re-deriving it was making things worse.
   What was here: two 52vw blurred blobs of green and yellow at 20%, which washed
   the whole product in a colour.
   Nacre is interference, not a pigment: the same surface throws warm and cool
   depending where you stand. So four very low-opacity washes at different
   angles, plus a fine grain. No single one is nameable; together they read as
   depth rather than as a colour. */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(120% 90% at 12% 8%,  rgba(255,247,235,.85) 0%, rgba(255,247,235,0) 60%),
    radial-gradient(100% 80% at 88% 12%, rgba(232,240,247,.80) 0%, rgba(232,240,247,0) 58%),
    radial-gradient(110% 95% at 78% 92%, rgba(250,236,240,.75) 0%, rgba(250,236,240,0) 62%),
    radial-gradient(120% 90% at 8%  95%, rgba(236,246,241,.70) 0%, rgba(236,246,241,0) 60%),
    linear-gradient(160deg,#FDFBF8 0%,#FAF8F6 38%,#F8F7F8 62%,#FBF9F5 100%);
}
/* The grain. Inline SVG turbulence — one gzipped line rather than an image
   request, and it does not tile visibly the way a small PNG does. */
body::after{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  opacity:.42; mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.45'/%3E%3C/svg%3E");
}

/* kept so any page still carrying the old markup renders identically */
.aura{position:fixed; inset:0; z-index:0; pointer-events:none; overflow:hidden}
.aura b{display:none}

/* Content must sit ABOVE the aura. The aura is position:fixed with z-index:0,
   and a positioned element paints above non-positioned blocks whatever the
   source order — so a page that forgot the .shell wrapper had its white cards
   tinted green by the light meant to sit behind them. .wrap carries the lift
   itself now, so no page can get this wrong. */
.shell{position:relative; z-index:1}
.wrap{position:relative; z-index:1; max-width:1416px; margin:0 auto; padding:0 40px}
@media(max-width:640px){.wrap{padding:0 22px}}

/* ------------------------------------------------------------------ type -- */
h1,.h1{
  font-family:var(--disp); font-weight:900; letter-spacing:-.045em;
  font-size:clamp(44px,8vw,116px); line-height:.88; margin:0; text-wrap:balance;
}
h2,.h2{
  font-family:var(--disp); font-weight:800; letter-spacing:-.035em;
  font-size:clamp(30px,4.6vw,58px); line-height:.98; margin:0; text-wrap:balance;
}
h3{font-family:var(--disp); font-weight:800; font-size:15px; letter-spacing:-.02em; margin:0}
.g{background:var(--sweep); -webkit-background-clip:text; background-clip:text; color:transparent}
.lead{font-size:15.5px; font-weight:400; color:var(--ink-2); max-width:66ch; margin:14px 0 0}
.sub{font-size:clamp(18px,2vw,24px); font-weight:300; line-height:1.45; color:var(--ink-2); max-width:34ch; margin:34px 0 0}
.sub b,.lead b{color:var(--ink); font-weight:500}
.lbl{font-size:14px; color:var(--ink-3); margin-bottom:18px}
/* the qualifier under a figure — who the number actually refers to{font-size:11.5px; color:var(--ink-3); opacity:.85; margin-top:3px; max-width:26ch; line-height:1.4}
p{color:var(--ink-2); max-width:66ch}
b,strong{color:var(--ink); font-weight:500}
.num{font-variant-numeric:tabular-nums}

/* ------------------------------------------------------- the command bar -- */
/* FIXED, not sticky. Sticky let the bar travel with the page until it caught —
   so it drifted on every scroll and felt loose. It is the one element that must
   never move. .page/.shell/.signin carry the matching top offset. */
/* ===========================================================================
   THE BAR MUST NOT MOVE. EVER. ON ANY PAGE.
   ---------------------------------------------------------------------------
   This app is five separate documents. Navigating between them tears down the
   whole DOM and builds a new one, so the bar was being destroyed and repainted
   on every click — that is the flicker, and no amount of "render it earlier"
   fixes it, because the element genuinely ceases to exist.

   The fix is to make the browser treat the bar as the SAME ELEMENT across two
   documents:

     @view-transition{navigation:auto}   opt this origin into cross-document
                                         transitions — the outgoing frame is
                                         held on screen until the incoming
                                         document is ready to paint, so there is
                                         never a blank moment
     view-transition-name:v-bar          names the bar in BOTH documents, so the
                                         browser pairs them and carries the old
                                         one straight through
     animation-duration:0s on its group  the paired bar does not animate, morph
                                         or cross-fade — it simply persists

   Three rules that must survive any future edit to this file:
     1. every page's bar element is <nav class="bar" id="v-bar"> — identical
        markup, identical position in the document, no exceptions
     2. nothing may be appended to or removed from the bar after first paint
        (the Admin tab ships hidden and is only revealed)
     3. no other rule may claim the name v-bar, and the geometry below is
        absolute — never relative to a parent that differs between pages
   =========================================================================== */
@view-transition{navigation:auto}
::view-transition-group(v-bar){animation-duration:0s}
::view-transition-old(v-bar),::view-transition-new(v-bar){animation:none; mix-blend-mode:normal; height:100%}
/* The content beneath cross-fades quickly and gets out of the way — the pill is
   the thing the eye should follow, so nothing else is allowed to animate for as
   long as it does. */
::view-transition-old(root){animation:v-fade-out .09s linear both}
::view-transition-new(root){animation:v-fade-in .14s linear both}
@keyframes v-fade-out{to{opacity:0}}
@keyframes v-fade-in{from{opacity:0}}
@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}

.bar{
  view-transition-name:v-bar;
  position:fixed; top:14px; left:50%; transform:translateX(-50%); z-index:60;
  width:min(1488px,calc(100% - 32px));
  display:flex; align-items:center; gap:6px; padding:9px 9px 9px 20px;
  background:rgba(255,255,255,.72); backdrop-filter:blur(24px) saturate(180%);
  -webkit-backdrop-filter:blur(24px) saturate(180%);
  border:1px solid var(--line); border-radius:var(--r-pill); box-shadow:var(--shadow);
}
.bar__mark{display:flex; align-items:center; gap:10px; margin-right:auto; color:inherit}
/* The client's mark sits in the slot Virya's rotor used to occupy. The SIZE is
   the product's and lives here; the IMAGE is the client's and comes from
   brand.css. Without this rule the <img> falls back to its own width/height
   attributes — 202x180 — and takes the whole bar with it. */
.bar__logo{height:30px; width:auto; max-width:160px; object-fit:contain; display:block; flex:0 0 auto}
.rotor{position:relative; width:26px; height:26px; flex:0 0 26px}
.rotor::before{
  content:""; position:absolute; inset:0; border-radius:50%;
  background:var(--sweep-conic);
  -webkit-mask:radial-gradient(circle,transparent 52%,#000 54%);
          mask:radial-gradient(circle,transparent 52%,#000 54%);
  animation:rotor-spin 18s linear infinite;
}
@keyframes rotor-spin{to{transform:rotate(360deg)}}
.bar__name{font-family:var(--disp); font-weight:800; font-size:16px; letter-spacing:-.02em;
  white-space:nowrap; color:var(--ink-3); padding-left:11px; border-left:1px solid var(--line-2)}
.bar__name em{font-style:normal; color:var(--ink-3); font-weight:700}
.bar__nav{display:flex; align-items:center; gap:4px; flex-wrap:wrap}
.nav{
  padding:9px 17px; border-radius:var(--r-pill); font-size:14.5px; font-weight:500;
  color:var(--ink-2); white-space:nowrap; transition:.2s var(--ease); cursor:pointer;
}
.nav:hover{background:var(--mist); color:var(--ink)}
.nav.locked{color:var(--ink-3)}

/* ---- the selector: a rotor line that travels, not a pill that balloons ------
   The active tab was a filled black pill. Across a navigation the browser has to
   morph that pill from the width of one word to the width of another — so
   "PowerProposal" collapsing into "Signals" visibly inflates and deflates. A
   solid box cannot change width gracefully; there is no reading of that motion
   except stretching.

   A 3px line can. It is the rotor sweep — the one piece of colour in this system
   — sitting under the active tab, and when it travels along the bar the width
   change reads as the line SLIDING, which is exactly what it is. The label
   itself just darkens.

   Same mechanism as before: the line is a named pseudo-element, so the browser
   pairs the old page's line with the new page's line and moves one into the
   other. The labels are unnamed and never move. */
.nav{position:relative; z-index:0}
.nav.on{color:var(--ink); font-weight:600}
.nav.on::after{
  content:""; position:absolute; left:16px; right:16px; bottom:2px; height:3px;
  border-radius:3px; background:var(--sweep);
  view-transition-name:v-pill;
}
::view-transition-group(v-pill){
  /* long enough to follow across the bar, with a settle at the end so it reads
     as a switch landing rather than a redraw */
  animation-duration:.44s;
  animation-timing-function:cubic-bezier(.32,1.12,.4,1);
  z-index:1;
}
/* both frames are the same gradient — cross-fading them only smears the travel */
::view-transition-old(v-pill),::view-transition-new(v-pill){animation:none; opacity:1}
/* the identity slots keep their width before /api/me resolves, so filling them
   in cannot nudge the bar sideways */
.bar__who{display:flex; align-items:center; gap:10px; padding-left:10px; margin-left:6px;
  border-left:1px solid var(--line); font-size:14px; color:var(--ink-2); white-space:nowrap}
.bar__who .av{width:24px; height:24px; flex:0 0 24px; border-radius:50%;
  background:var(--mist); border:1px solid var(--line); display:grid; place-items:center;
  font-size:11px; font-weight:600; color:var(--ink-2)}
#v-user{min-width:38px; display:inline-block}
.nav[hidden]{display:none}

/* ---- the account menu ----------------------------------------------------
   Hovering the name opens it; it is absolutely positioned so nothing it does
   can change the bar's width and nudge the tabs. focus-within keeps it usable
   from the keyboard, and the padding above the panel is a deliberate bridge so
   the pointer can travel from the name to Sign out without crossing a gap and
   closing it. */
.bar__who{position:relative; cursor:default; outline:none}
.who__chev{color:var(--ink-3); transition:transform .18s var(--ease), color .18s}
.bar__who:hover .who__chev,.bar__who:focus-within .who__chev{transform:rotate(180deg); color:var(--ink-2)}
.who__menu{
  position:absolute; top:100%; right:0; padding-top:12px;
  opacity:0; pointer-events:none; transform:translateY(-4px);
  transition:opacity .16s var(--ease), transform .16s var(--ease);
  display:flex; flex-direction:column; min-width:186px; z-index:70;
}
.bar__who:hover .who__menu,.bar__who:focus-within .who__menu{opacity:1; pointer-events:auto; transform:none}
.who__menu > *{background:var(--w)}
.who__me{display:flex; flex-direction:column; gap:1px; padding:11px 14px 9px;
  border:1px solid var(--line); border-bottom:0; border-radius:12px 12px 0 0;
  font-size:11.5px; color:var(--ink-3); box-shadow:var(--shadow)}
.who__me b{font-size:13.5px; color:var(--ink); font-weight:600}
.who__out{display:flex; align-items:center; gap:9px; padding:10px 14px;
  border:1px solid var(--line); border-radius:0 0 12px 12px; box-shadow:var(--shadow);
  font-size:13.5px; color:var(--ink-2); text-decoration:none; transition:.14s var(--ease)}
.who__out:hover{background:var(--mist); color:var(--ink)}
.bar__burger{display:none; margin-left:auto; border:1px solid var(--line); background:var(--w);
  border-radius:var(--r-pill); padding:9px 15px; font:inherit; font-size:14px; cursor:pointer}
@media(max-width:900px){
  .bar{flex-wrap:wrap}
  .bar__burger{display:block}
  .bar__nav,.bar__who{display:none; width:100%}
  .bar.is-open .bar__nav{display:flex; padding:8px 0 4px}
  .bar.is-open .bar__who{display:flex; border-left:0; padding:8px 0 2px; border-top:1px solid var(--line)}
  /* on a phone the bar is an open list, not a hover surface — show the sign-out
     inline rather than behind a hover that a touch screen cannot perform */
  .bar.is-open .who__menu{position:static; opacity:1; pointer-events:auto; transform:none;
    padding-top:0; margin-left:auto; min-width:0}
  .bar.is-open .who__me{display:none}
  .bar.is-open .who__out{border-radius:var(--r-pill); box-shadow:none}
  .who__chev{display:none}
}

/* every layout clears the fixed bar — one variable, so it can never drift out
   of step with the bar's own height */
:root{--bar-clear:84px}
.page{padding-top:var(--bar-clear); padding-bottom:60px}
/* .shell already carries --bar-clear; adding it to the head slot too pushed
   the QuickLegal header down by twice the bar height. */
.signin{padding-top:calc(var(--bar-clear) - 40px)}
@media(max-width:900px){:root{--bar-clear:92px}}

/* ------------------------------------------------- the page head / menu ---- */
/* The SUB-MENU is the title. The section you are in is set in display type and
   its siblings sit beside it, greyed — navigation reads as content instead of a
   second bar of chrome. These rules were written for the design mock and were
   missing here, so every section menu rendered as run-together plain text. */
/* The section menu is written into .v-head-slot by JavaScript. The slot ships
   EMPTY, so until that runs the page has no header at all and everything below
   it sits ~90px too high — then the header lands and the whole page jumps down.
   That jump happens on every navigation and is the jerk you see after the bar
   itself has stopped moving.

   Reserving the height costs nothing and removes the shift entirely: the space
   is already there, the header simply fills it. min-height, not height, so a
   page whose menu wraps to two lines still grows normally. */
/* Reserved so the header does not appear from nothing while JS runs. With
   .titles pinned to one line this is now also the FINAL height in every app, not
   just a floor — the crumb, the title row and its margin, and nothing that can
   grow with the number of sections. */
.v-head-slot{min-height:104px}
@media(max-width:640px){.v-head-slot{min-height:96px}}
.head{padding:6px 0 0; margin-bottom:22px}
.crumb{font-size:12.5px; color:var(--ink-3); margin-bottom:14px; line-height:1.4}
/* ONE LINE, ALWAYS. This menu used to wrap, so its height depended on how many
   sections an app has and how wide the window is: Signals' six titles took three
   lines and 217px, Admin's five took two and 160px. Switching between them
   collapsed the header by 57px and threw every pane's content up the page — read
   as the nav jerking, though the bar itself never moved.

   A section menu is navigation, not prose. It stays on one line and scrolls
   sideways if it must, so the header is exactly the same height in every app and
   nothing below it can be moved by a change of section count. */
.titles{display:flex; align-items:baseline; gap:22px; flex-wrap:nowrap; line-height:1.5;
  overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none;
  padding-bottom:2px; scroll-snap-type:x proximity}
.titles::-webkit-scrollbar{display:none}
.titles a{flex:none; scroll-snap-align:start}
.titles a{
  font-family:var(--disp); font-weight:900; letter-spacing:-.04em; line-height:.95;
  color:var(--ink-3); font-size:clamp(15px,1.5vw,17px);
  cursor:pointer; text-decoration:none; transition:color .25s var(--ease);
}
.titles a:hover{color:var(--ink-2)}
.titles a.on{color:var(--ink); font-size:clamp(22px,2.6vw,28px)}
.titles a .cnt{
  font-family:var(--body); font-weight:400; font-size:12px; letter-spacing:0;
  color:var(--ink-3); vertical-align:super; margin-left:7px;
  font-variant-numeric:tabular-nums;
}

/* third level — quiet links with a sliding rotor underline */
.third{display:flex; gap:24px; margin:24px 0 0; border-bottom:1px solid var(--line); flex-wrap:wrap}
.third a{
  position:relative; padding:0 0 11px; font-size:13.5px; font-weight:500;
  color:var(--ink-3); cursor:pointer; text-decoration:none; transition:color .2s;
}
.third a:hover{color:var(--ink-2)}
.third a.on{color:var(--ink)}
.third a.on::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px;
  background:var(--sweep); border-radius:2px;
}

/* -------------------------------------------------------------- sections -- */
.sect{padding:26px 0}
.tone{background:var(--mist)}
.split{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:60px; align-items:start}
@media(max-width:900px){.split{grid-template-columns:minmax(0,1fr); gap:36px}}

/* ------------------------------------------------------------------ card -- */
.card{
  position:relative; background:var(--w); border:1px solid var(--line);
  border-radius:var(--r); padding:14px 15px 13px; overflow:hidden;
  transition:transform var(--t), box-shadow var(--t);
}
.card.is-off{opacity:.5}
.card__role{font-size:12px; color:var(--ink-3); margin-top:3px}
.card__body{font-size:13px; font-weight:400; color:var(--ink-2); line-height:1.5; margin:7px 0 0}
.cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(265px,1fr)); gap:10px}

/* --------------------------------------------------------------- figures -- */
/* a hairline-separated strip of big numbers. NOT `.band` — admin.js uses that
   name for a plain white container, and one class cannot be both a grid and a
   block without slicing the container's heading into columns. */
.figures{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:1px;
  background:var(--line); border:1px solid var(--line); border-radius:var(--r); overflow:hidden;
}
.figures > *{background:var(--w); padding:13px 15px}
.figures .n{font-family:var(--disp); font-weight:800; font-size:clamp(22px,2.6vw,32px);
  letter-spacing:-.035em; line-height:1; font-variant-numeric:tabular-nums}
.figures .l{font-size:12px; color:var(--ink-3); margin-top:4px}

/* ----------------------------------------------------------------- state -- */
.st{display:inline-flex; align-items:center; gap:8px; font-size:13.5px; color:var(--ink-2)}
.st i{width:6px; height:6px; border-radius:50%; background:var(--ink-3); flex:0 0 6px}
.st--ok{color:var(--green-ink)}    .st--ok i{background:var(--green)}
.st--bad{color:var(--red-ink)}     .st--bad i{background:var(--red)}

.pill{
  display:inline-flex; align-items:center; gap:7px; padding:3px 11px;
  background:var(--w); border:1px solid var(--line); border-radius:var(--r-pill);
  font-size:12.5px; color:var(--ink-2);
}
.pill--ok{color:var(--green-ink); border-color:rgba(108,180,60,.4); background:rgba(108,180,60,.09)}
.pill--warn{color:var(--yellow-ink); border-color:rgba(252,216,0,.5); background:rgba(252,216,0,.13)}
/* anything a model produced is marked{
  color:var(--ink); border:1px solid transparent;
  background:linear-gradient(var(--w),var(--w)) padding-box, var(--sweep) border-box;
}

/* -------------------------------------------------------------- controls -- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:36px; padding:0 17px; border-radius:var(--r-pill);
  background:var(--w); color:var(--ink); border:1px solid var(--line-2);
  font:inherit; font-size:13.5px; font-weight:500; cursor:pointer;
  transition:.2s var(--ease); white-space:nowrap; text-decoration:none;
}
.btn:hover{background:var(--mist)}
.btn--go{background:var(--ink); color:var(--w); border-color:var(--ink)}
.btn--go:hover{background:#000; box-shadow:var(--shadow)}
.btn--ghost{background:transparent; border-color:var(--line); color:var(--ink-2)}
.btn:disabled{opacity:.4; cursor:not-allowed}
.btn--sm{min-height:30px; padding:0 13px; font-size:12.5px}

/* Select by what an input ISN'T, not by an allow-list of types. `<input>` with no
   type attribute defaults to text and matched none of the listed selectors, so a
   field could silently render unstyled beside a styled one — which is exactly
   what happened to the sign-in user field. */
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]):not([type=color]):not([type=submit]):not([type=button]):not([type=image]):not([type=hidden]),
select,textarea,.in{
  width:100%; min-height:36px; padding:8px 13px;
  /* A FIELD MUST NOT LOOK LIKE A CARD. These were white on white with a hairline
     border, so on a white panel there was nothing to say "you can type here" —
     read-only data and an entry field were the same shade. The field is a WELL:
     recessed tint, a real border, and it turns white the moment you focus it, so
     the one you are editing is the one that is lit. */
  background:var(--mist); color:var(--ink);
  border:1px solid var(--line-2); border-radius:var(--r-sm);
  font:inherit; font-size:14px; transition:.2s var(--ease);
}
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]):hover,
select:hover,textarea:hover{border-color:var(--ink-3)}
input[readonly],input:disabled,textarea[readonly],textarea:disabled,select:disabled{
  background:transparent; border-style:dashed; color:var(--ink-2); cursor:default;
}
input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]):focus,
select:focus,textarea:focus{
  outline:none; background:var(--w);
  border-color:var(--green); box-shadow:0 0 0 4px rgba(108,180,60,.14);
}
textarea{min-height:96px; line-height:1.55; resize:vertical}
label{display:block; font-size:11.5px; font-weight:600; letter-spacing:.04em;
  text-transform:uppercase; color:var(--ink-3); margin-bottom:5px}

/* ---------------------------------------------------------------- tables -- */
.table-wrap{overflow-x:auto; border:1px solid var(--line); border-radius:var(--r); background:var(--w)}
table{width:100%; border-collapse:collapse; min-width:520px}
th{
  text-align:left; padding:7px 12px; background:var(--mist);
  border-bottom:1px solid var(--line); font-size:14px; font-weight:500;
  color:var(--ink-3); white-space:nowrap;
}
td{padding:7px 12px; border-bottom:1px solid var(--line); font-size:13px; color:var(--ink-2)}
tr:last-child td{border-bottom:0}
tbody tr:hover td{background:var(--mist)}
td.fig{text-align:right; font-variant-numeric:tabular-nums; color:var(--ink); font-weight:500}

/* ---------------------------------------------------------------- sheets -- */
.veil{
  position:fixed; inset:0; z-index:200; display:grid; place-items:center; padding:24px;
  background:rgba(11,14,13,.34); backdrop-filter:blur(6px);
  animation:veil-in .2s var(--ease);
}
@keyframes veil-in{from{opacity:0}}
.sheet{
  width:100%; max-width:520px; max-height:86vh; overflow-y:auto;
  background:var(--w); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:0 60px 120px -50px rgba(11,14,13,.7); padding:22px;
  animation:sheet-in .3s var(--ease);
}
@keyframes sheet-in{from{opacity:0; transform:translateY(14px) scale(.985)}}
.sheet h3{font-size:20px; margin-bottom:5px}
.sheet p{font-weight:300; margin:12px 0 0}
.sheet__acts{display:flex; gap:10px; justify-content:flex-end; margin-top:26px; flex-wrap:wrap}

/* --------------------------------------------------------- working light -- */
/* The rotor speeds up while a model thinks. No spinner, no separate widget —
   the mark already in the bar is the indicator. */
.working{
  position:fixed; left:50%; transform:translateX(-50%); bottom:26px; z-index:150;
  display:flex; align-items:center; gap:12px; padding:11px 22px 11px 14px;
  background:rgba(255,255,255,.82); backdrop-filter:blur(20px) saturate(180%);
  border:1px solid var(--line); border-radius:var(--r-pill); box-shadow:var(--shadow);
  font-size:14.5px; color:var(--ink-2); max-width:min(520px,calc(100vw - 40px));
}
/* ============================================================================
   PART 2 — legacy class names{display:flex; align-items:center; gap:14px; padding:0 0 24px; background:none; border:0}
.tabs{display:flex; gap:6px; overflow-x:auto; scrollbar-width:none; margin:8px 0 34px; border:0; padding:0}
.tabs::-webkit-scrollbar{display:none}
.tab{
  flex:0 0 auto; min-height:32px; padding:6px 15px; border:1px solid var(--line);
  background:var(--w); color:var(--ink-2); font:inherit; font-size:15px; font-weight:500;
  border-radius:var(--r-pill); cursor:pointer; white-space:nowrap; transition:.2s var(--ease);
}
.tab:hover{background:var(--mist); color:var(--ink)}
.tab[aria-selected="true"],.tab.active,.tab.on{background:var(--ink); color:var(--w); border-color:var(--ink)}
.section,
.panel,
.pipe,
.inv{
  background:var(--w); border:1px solid var(--line); border-radius:var(--r);
  margin:16px 0; overflow:hidden;
}
.section > summary,
.pipe-head{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:11px 15px; font-family:var(--disp); font-weight:800; font-size:15px;
  letter-spacing:-.025em; color:var(--ink); cursor:pointer; list-style:none;
}
.section > summary::-webkit-details-marker{display:none}
.section > summary::after{content:"›"; transform:rotate(90deg); color:var(--ink-3); font-size:22px; transition:.2s}
.section[open] > summary::after{transform:rotate(-90deg)}
.section > .body,
.pipe-body{padding:0 15px 15px}

.hero{padding:0 0 44px; background:none; border:0}
.grid,
.agents,
.findings{display:grid; gap:18px;
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.chip{
  display:inline-flex; align-items:center; gap:6px; padding:3px 10px;
  border-radius:var(--r-pill); border:1px solid var(--line); background:var(--w);
  font-size:12.5px; color:var(--ink-2);
}
.chip--approved{color:var(--green-ink); border-color:rgba(108,180,60,.4); background:rgba(108,180,60,.09)}
.chip--draft{color:var(--ink-3)}
.chips{display:flex; gap:8px; flex-wrap:wrap}
.btn--ghost{border-radius:var(--r-pill)}
.modal{width:100%; max-width:560px; max-height:86vh; overflow-y:auto; background:var(--w);
  border:1px solid var(--line); border-radius:var(--r); padding:34px;
  box-shadow:0 60px 120px -50px rgba(11,14,13,.7)}
.modal h3{font-family:var(--disp); font-weight:800; font-size:26px; letter-spacing:-.03em; margin:0 0 10px}
.modal .row{display:flex; gap:10px; justify-content:flex-end; margin-top:24px; flex-wrap:wrap}

.scroll-x{width:100%; overflow-x:auto}
@keyframes fade{from{opacity:0; transform:translateY(8px)}}
/* the old flow/step components — kept structural,
.step,
.node{background:var(--w); border:1px solid var(--line);
  border-radius:var(--r-sm); padding:18px 20px; margin:10px 0}
.dot{width:8px; height:8px; border-radius:50%; background:var(--ink-3); display:inline-block}
.eyebrow{font-size:14px; color:var(--ink-3)}

@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}


/* ============================================================================
   THE BLOCK SYSTEM — the shared language of the screens built on top of Virya's
   sheet (Signals' Shopify boards, Shopification, the mirror explorer).
   It introduces NO colours of its own: bands come from --sc-band, which
   brand.css sets per client, and everything else is Virya's tokens.
   ========================================================================== */
.j-band{
  background:var(--sc-band,var(--mist)); color:var(--sc-band-fg,var(--ink));
  padding:15px 18px 14px; display:flex; align-items:baseline;
  justify-content:space-between; gap:18px; flex-wrap:wrap;
  border-bottom:1px solid var(--sc-band-rule,var(--line));
  border-radius:var(--r) var(--r) 0 0;
}
.j-band h2,.j-band .j-title{
  margin:0; font-family:var(--disp); font-weight:800; font-size:21px; line-height:1.05;
  letter-spacing:-.03em; color:var(--sc-band-num,var(--ink));
}
.j-band .j-asof{font-size:12.5px; color:var(--sc-band-mute,var(--ink-3))}

.j-figs{display:grid; grid-template-columns:repeat(4,minmax(0,1fr));
  background:var(--sc-band,var(--mist)); color:var(--sc-band-fg,var(--ink));
  border-bottom:1px solid var(--sc-band-rule,var(--line))}
@media(max-width:720px){.j-figs{grid-template-columns:repeat(2,minmax(0,1fr))}}
.j-figs > *{padding:15px 18px 16px; border-right:1px solid var(--sc-band-rule,var(--line))}
.j-figs > *:last-child{border-right:0}
.j-figs .n{display:block; font-family:var(--disp); font-weight:800; font-size:30px;
  line-height:1; letter-spacing:-.035em; color:var(--sc-band-num,var(--ink));
  font-variant-numeric:tabular-nums}
.j-figs .l{margin-top:8px; font-size:11.5px; color:var(--sc-band-fg,var(--ink-2))}
.j-figs .s{margin-top:5px; font-size:11.5px; color:var(--sc-band-mute,var(--ink-3))}

.j-block{padding:18px; border-bottom:1px solid var(--line)}
.j-block:last-child{border-bottom:0}
.j-block > h3{
  margin:0 0 5px; font-family:var(--disp); font-weight:800; font-size:15px;
  letter-spacing:-.02em; display:flex; align-items:center; gap:8px;
}
.j-block > h3::before{
  content:""; width:14px; height:3px; flex:none; border-radius:2px;
  background:var(--sc-band,var(--accent,var(--red)));
}
.j-block > .j-note{margin:0 0 13px; font-size:13px; color:var(--ink-3); max-width:62em}

.j-tw{overflow-x:auto}
.j-tbl{width:100%; border-collapse:collapse}
.j-tbl th{
  text-align:left; font-size:11px; font-weight:600; color:var(--ink-3);
  padding:9px 12px 8px; border-bottom:2px solid var(--sc-band,var(--line));
  white-space:nowrap;
}
.j-tbl td{padding:11px 12px; border-bottom:1px solid var(--line); font-size:13.5px}
.j-tbl tr:last-child td{border-bottom:0}
.j-tbl td.num,.j-tbl th.num{text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap}
.j-tbl td.key{font-weight:600; white-space:nowrap}
.j-tbl td.key em{font-style:normal; font-weight:400; color:var(--ink-3)}

.j-flag{display:inline-block; font-size:11px; font-weight:600; padding:3px 8px;
  border-radius:var(--r-sm); border:1px solid var(--red); color:var(--red-ink);
  background:rgba(192,36,36,.07); white-space:nowrap}
.j-flag--quiet{border-color:var(--line-2); color:var(--ink-3); background:transparent}
.j-ok{color:var(--ink-3); font-size:13px}

/* ============================================================================
   DIALOGS — appAlert / appConfirm / appPrompt / appForm, and the working chip.

   THESE HAD NO STYLING AT ALL. q.js has always emitted .v-veil / .v-sheet /
   .v-btn / .v-lbl — the class names from the Virya sheet this stylesheet
   replaced — and the rebuild took the names with it. So every dialog in the
   platform ("Remove this role?", every error) was rendering as raw unstyled
   HTML at the top of the document: no overlay, no panel, no buttons.

   Renaming the classes in q.js would have been the tidier fix and the wrong
   one — it is a shared primitive loaded by every app, and the names are also in
   markup this stylesheet cannot see. The names stay; the styling comes back, on
   this product's own tokens.
   ========================================================================== */
.v-veil{position:fixed; inset:0; z-index:200; padding:22px;
  background:rgba(0,0,0,.42); display:grid; place-items:center}
.v-sheet{width:min(460px,100%); max-height:86dvh; overflow:auto; padding:24px;
  background:var(--w); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow-lift, 0 18px 48px rgba(0,0,0,.18))}
.v-sheet h3{margin:0 0 10px; font:600 19px/1.25 var(--disp, inherit); color:var(--ink)}
/* A confirm is a QUESTION AND ITS CONSEQUENCE. The sentence under the title is
   what somebody is agreeing to, so it gets reading measure and real contrast —
   not the muted caption treatment a label would take. */
.v-sheet p{margin:0 0 18px; max-width:56ch; font-size:13.5px; line-height:1.6;
  color:var(--ink-2)}
.v-sheet .v-lbl{display:block; margin:0 0 6px; font-size:11.5px; font-weight:600;
  letter-spacing:.04em; text-transform:uppercase; color:var(--ink-3)}
.v-sheet input,.v-sheet select,.v-sheet textarea{margin-bottom:14px}
/* Actions right-aligned, confirm last: the destination of the eye is the button
   that does the thing, and Cancel must never be the one under the cursor. */
.v-sheet__acts{display:flex; justify-content:flex-end; gap:10px; margin-top:20px;
  padding-top:16px; border-top:1px solid var(--line)}
.v-btn{display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:36px; padding:0 17px; border-radius:var(--r-pill); cursor:pointer;
  background:var(--w); color:var(--ink); border:1px solid var(--line-2);
  font:inherit; font-size:13.5px; font-weight:500; white-space:nowrap;
  transition:.2s var(--ease)}
.v-btn:hover{background:var(--mist)}
.v-btn--go{background:var(--ink); color:var(--w); border-color:var(--ink)}
.v-btn--go:hover{background:#000; box-shadow:var(--shadow)}
.v-btn--quiet{background:transparent; border-color:var(--line); color:var(--ink-2)}
.v-btn--quiet:hover{background:var(--mist); color:var(--ink)}
.v-btn--danger{color:var(--red-ink); border-color:rgba(192,36,36,.3);
  background:rgba(192,36,36,.06)}
.v-btn--danger:hover{background:rgba(192,36,36,.12)}
.v-btn:focus-visible{outline:2px solid var(--ink); outline-offset:2px}

/* The "working" chip, bottom-left and clear of everything. */
.v-working{position:fixed; left:18px; bottom:18px; z-index:190;
  display:flex; align-items:center; gap:10px; padding:9px 14px;
  background:var(--w); border:1px solid var(--line); border-radius:var(--r);
  box-shadow:var(--shadow)}
.v-working__txt{font-size:12.5px; color:var(--ink-2)}
