/* ⛔ THE APP'S OWN SCOPE, NOT THE SHELL'S. Every rule below used to be
   `body.os.inthread …`, which bound the Passwords screen to one surface: on the
   Work OS home (index.html) `inthread` is a real page MODE, so opening the app
   from a company's app grid would have switched the whole page into the thread
   view to get its own stylesheet. The rules hang off `.osApp` — the app root —
   so the app draws the same wherever the shell mounts it. The one rule that is
   genuinely about the shell (hiding the conversation underneath) keeps its
   shell selector. */
/* Passwords — the app body. Header / gutter / tokens come from os-app.css.
   Ladder only. Colour is state. Every number is mono. */
body.os.inthread.osAppOpen #osMain .thread,
body.os.inthread.osAppOpen #osMain .composer,
body.os.inthread.osAppOpen #osMain .rhead{visibility:hidden}


/* ⛔ THE BAR AND THE REFUSAL BOX ARE THE SHELL'S TOO, as of 2026-08-29.
   `.osVaultBar` and `.osVaultRefuse` lived here and re-invented the app frame;
   Site X-ray had its own twins a pane away, so the two drifted the first time
   either was touched. They are `.osAppBar` and `.osAppRefuse` in os-app.css now.
   SPEC-APP-STANDARD §2. */
/* ⛔ THE TABS THEMSELVES ARE THE SHELL'S (os-app.css). This app duplicated
   every one of those rules — layout, the button, the `.on` state — so the two
   sheets drifted apart the first time either was touched and the app stopped
   matching the app beside it. Only the COUNT is ours, because only this app
   puts a number in a tab. */
.osApp .osAppCard .tabs .n{font:400 11px var(--osMono);color:var(--faint);margin-left:5px}

.osApp .osVaultList{display:flex;flex-direction:column;gap:5px}
/* ⛔ THE ROW IS NO LONGER A BUTTON — a button may not contain the Reveal and
   Copy buttons the row now carries. The row is the container; the title is the
   control that opens the drawer; the actions sit beside it and do not open it. */
.osApp .osVaultRow{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;align-items:center;
  padding:10px 12px 10px 14px;border:1px solid var(--line);border-radius:10px;
  background:transparent;color:var(--ink)}
.osApp .osVaultRow:hover{background:var(--surf);border-color:var(--line2)}
.osApp .osVaultRow.isOpen{border-color:var(--line2);background:var(--surf)}
.osApp .osVaultOpen{
  display:block;width:100%;min-width:0;text-align:left;padding:2px 0;
  border:0;background:transparent;color:inherit;cursor:pointer;font:inherit}
.osApp .osVaultOpen:focus-visible{outline:2px solid var(--violet);outline-offset:3px;border-radius:6px}
.osApp .osVaultRow .t{
  display:block;font:500 13.5px/1.35 var(--osDisp);color:var(--ink)}
.osApp .osVaultRow .s{
  display:block;font:400 11.5px/1.45 var(--osMono);color:var(--muted);margin-top:3px}
/* The revealed value lives in the row, and it is the loudest thing there —
   mono, boxed, so it can never be mistaken for the title or the host. */
.osApp .osVaultRow .v{
  display:block;margin-top:7px;padding:6px 10px;border-radius:7px;
  border:1px solid color-mix(in srgb,var(--violet) 35%,var(--line));
  background:color-mix(in srgb,var(--violet) 7%,transparent);
  font:400 12.5px/1.45 var(--osMono);color:var(--ink);word-break:break-all}
.osApp .osVaultAct{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:flex-end}
/* ⚡ The row's actions stay quiet until the row is wanted — visible on hover,
   on focus, and always on a touch screen, where there is no hover to reveal
   them and a hidden control is simply a missing one. */
.osApp .osVaultAct .ghost{
  padding:5px 11px;border:1px solid var(--line);border-radius:999px;
  background:var(--surf);color:var(--muted);font:400 11.5px var(--body);cursor:pointer;
  opacity:0;transition:opacity .12s ease}
.osApp .osVaultRow:hover .ghost,
.osApp .osVaultRow.isOpen .ghost,
.osApp .osVaultAct .ghost:focus-visible{opacity:1}
@media (hover:none){.osApp .osVaultAct .ghost{opacity:1}}
.osApp .osVaultAct .ghost:hover{color:var(--ink);border-color:var(--line2)}
.osApp .osVaultFlags{display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.osApp .osVaultFlags.start{justify-content:flex-start;margin:0 0 4px}
.osApp .osVaultFlags span{
  font:400 10.5px var(--osMono);color:var(--faint);
  border:1px solid var(--line);border-radius:999px;padding:2px 8px}
.osApp .osVaultFlags .bad{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 45%,var(--line))}
.osApp .osVaultFlags .ok{color:var(--mint);border-color:color-mix(in srgb,var(--mint) 40%,var(--line))}


/* The subject switcher (SPEC-APP-STANDARD §3: `select` changes the SUBJECT and
   never navigates away). ⛔ It was rendering as the browser's own control —
   a grey OS widget in the middle of the product's chrome. The native element
   stays, because it is the one that works with a keyboard and on a phone; only
   its skin is ours, and the arrow is drawn rather than inherited. */
.osApp .rhTop .sel{
  margin-left:auto;padding:5px 26px 5px 12px;border:1px solid var(--line);border-radius:999px;
  background:var(--surf);color:var(--ink);font:400 12.5px var(--body);max-width:240px;
  -webkit-appearance:none;appearance:none;cursor:pointer;
  background-image:linear-gradient(45deg,transparent 50%,var(--muted) 50%),
                   linear-gradient(135deg,var(--muted) 50%,transparent 50%);
  background-position:calc(100% - 14px) 52%,calc(100% - 9px) 52%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat}
.osApp .rhTop .sel:hover{border-color:var(--line2);background-color:var(--surf2)}
.osApp .rhTop .sel:focus-visible{outline:2px solid var(--violet);outline-offset:2px}

/* ⛔ THE DRAWER USED TO GREY THE WHOLE SCREEN AND THEN SIT ON IT IN FROSTED
   GLASS — a dark wash over the list, a translucent panel over that, and the
   list's own cards showing through it as dim rectangles. Three layers of
   half-transparency stacked on each other read as damage, not depth, and
   nothing in it was quite legible.
   ⚡ Now: the panel is OPAQUE and sits in its own space with air around it, and
   the wash is a whisper — enough to say the list is not the active thing, not
   enough to make it look broken. On a wide screen the drawer stands BESIDE the
   content, so there is nothing to dim and the scrim is only a click target. */
.osApp .osDrawScrim{
  position:fixed;inset:54px 0 0 0;z-index:16;background:rgba(4,8,18,.14);border:0;cursor:pointer}
@media (min-width:1180px){
  .osApp .osDrawScrim{left:262px;right:324px;background:transparent}
}
.osApp .osDraw{
  position:fixed;top:54px;right:0;bottom:0;width:min(440px,100%);z-index:17;overflow:auto;
  border-left:1px solid var(--line);background:var(--bg);
  box-shadow:-18px 0 44px rgba(4,8,18,.16)}
/* ⚡ INSET, NOT WELDED TO THE EDGES. It was flush to the top, the right and the
   bottom of the viewport at once, so it read as part of the browser rather than
   as a panel belonging to this app. */
@media (min-width:1180px){
  .osApp .osDraw{
    right:334px;top:66px;bottom:12px;width:min(430px,42vw);
    border:1px solid var(--line);border-radius:14px;overflow:hidden auto}
}
/* ⛔ THE DRAWER IS A PAGE, NOT A STACK OF LOOSE LINES. It was a heading, three
   grid rows separated by hairlines and two bare buttons at the bottom left —
   every element the same weight, nothing owning anything. Now: a header that
   holds the title AND what the credential is FOR, the fields as cards, and the
   destructive pair pinned to a footer with a rule above it, so Delete can never
   be the thing your eye lands on first. */
.osApp .osDraw{display:flex;flex-direction:column;gap:14px;padding:18px 18px 0}
.osApp .osDraw h2{
  font:500 17px/1.32 var(--osDisp);letter-spacing:-.01em;margin:0;
  overflow-wrap:anywhere}
.osApp .osDraw .hd{
  display:flex;align-items:flex-start;gap:12px;padding-bottom:13px;
  border-bottom:1px solid var(--line)}
.osApp .osDraw .hdTx{min-width:0;display:flex;flex-direction:column;gap:3px}
.osApp .osDraw .hdSub{
  font:400 11.5px/1.4 var(--osMono);color:var(--muted);word-break:break-all}
.osApp .osDraw .hd .x{
  flex:none;margin-left:auto;padding:5px 13px;border:1px solid var(--line);border-radius:999px;
  background:var(--surf);color:var(--muted);cursor:pointer;font-size:12.5px}
.osApp .osDraw .hd .x:hover{color:var(--ink);border-color:var(--line2)}

.osApp .osFields{display:flex;flex-direction:column;gap:10px}
.osApp .osField{display:flex;flex-direction:column;gap:6px}
.osApp .osField .lab{
  font:400 11px var(--osMono);letter-spacing:.04em;text-transform:uppercase;color:var(--faint)}
/* The value and its actions are ONE card — that is what makes a hidden value
   read as a field in a state, rather than as grey text somebody forgot. */
.osApp .osField .fRow{
  display:flex;align-items:center;gap:9px;min-height:40px;
  padding:7px 8px 7px 12px;border:1px solid var(--line);border-radius:10px;
  background:var(--surf)}
.osApp .osField .val{
  flex:1;min-width:0;font:400 13px/1.45 var(--osMono);color:var(--ink);word-break:break-all}
.osApp .osField .val.hid{color:var(--faint);letter-spacing:.06em}
.osApp .osField .val .ttl{
  margin-left:8px;font-size:11px;color:var(--faint)}
.osApp .osField .fActs{display:flex;gap:6px;flex:none}
.osApp .osField button{
  padding:5px 12px;border:1px solid var(--line);border-radius:999px;
  background:var(--bg);color:var(--muted);font-size:12px;cursor:pointer;white-space:nowrap}
.osApp .osField button:hover{color:var(--ink);border-color:var(--line2)}
.osApp .osField button[disabled]{opacity:.42;cursor:default}
.osApp .osField button[disabled]:hover{color:var(--muted);border-color:var(--line)}

/* ⚡ The footer is sticky so Save is reachable without scrolling a long form,
   and it carries the drawer's own background — a translucent bar over scrolling
   text is unreadable exactly when it matters. */
/* ⛔ AND THE FOOTER IS NOT A FULL-WIDTH BAR. It stretched edge to edge with
   Save at one end and Delete at the other, which made the destructive button
   the far corner of the panel — the easiest thing to hit and the last thing
   you read. The two actions sit together at the start; Delete is separated by
   space, not by the width of the drawer. */
.osApp .osDrawActs{
  position:sticky;bottom:0;margin-top:auto;display:flex;gap:8px;flex-wrap:wrap;
  align-items:center;padding:13px 0 16px;border-top:1px solid var(--line);
  background:var(--bg)}
.osApp .osDrawActs .go{
  padding:8px 16px;border:0;border-radius:999px;background:var(--fill);color:var(--onfill);
  font:500 12.5px var(--body);cursor:pointer}
.osApp .osDrawActs button:not(.go):not(.danger){
  padding:8px 16px;border:1px solid var(--line);border-radius:999px;
  background:var(--surf);color:var(--muted);font-size:12.5px;cursor:pointer}
/* ⛔ Delete sits apart from the pair it is not part of. */
.osApp .osDrawActs .danger{
  margin-left:14px;padding:8px 16px;
  border:1px solid color-mix(in srgb,var(--rose) 45%,var(--line));
  border-radius:999px;background:transparent;color:var(--rose);font-size:12.5px;cursor:pointer}
.osApp .osDrawActs .danger:hover{background:color-mix(in srgb,var(--rose) 10%,transparent)}
.osApp .osForm{display:flex;flex-direction:column;gap:10px}
.osApp .osForm label{font-size:11.5px;color:var(--muted)}
.osApp .osForm input,.osApp .osForm select,.osApp .osForm textarea{
  width:100%;padding:9px 12px;border:1px solid var(--line);border-radius:9px;
  background:var(--bg);color:var(--ink);font:14px var(--body)}
.osApp .osForm input.mono{font:13px var(--osMono)}
.osApp .osForm .acts{display:flex;gap:7px;flex-wrap:wrap;margin-top:5px}
.osApp .osForm .go{
  padding:7px 14px;border:0;border-radius:999px;background:var(--fill);color:var(--onfill);
  font:500 12.5px var(--body);cursor:pointer}
.osApp .osForm .danger{
  padding:7px 14px;border:1px solid color-mix(in srgb,var(--rose) 50%,var(--line));
  border-radius:999px;background:transparent;color:var(--rose);font-size:12.5px;cursor:pointer}
.osApp .osAppNote{font:400 11px var(--osMono);color:var(--faint);margin-top:10px}

/* The row's primary copy — the same rule as the drawer: the safe action is the
   filled one, because it is the one that never puts a password on a screen. */
.osApp .osVaultAct .ghost.go{
  background:var(--fill);border-color:var(--fill);color:var(--onfill)}
.osApp .osVaultAct .ghost.go:hover{color:var(--onfill);filter:brightness(1.08)}
/* A one-line answer under a row — "no username stored", "the copy was refused".
   ⛔ It spans BOTH columns: put in the actions cell it would push the buttons
   around every time it appeared. */
.osApp .osVaultSay{
  grid-column:1/-1;margin-top:7px;font:400 11.5px/1.45 var(--osMono);color:var(--muted)}
.osApp .osVaultSay.bad{color:var(--amber)}

/* ── the technical fold ───────────────────────────────────────────────────── */
.osApp .osTech{border-top:1px solid var(--line);padding-top:12px;margin-top:2px}
.osApp .osTech>summary{
  cursor:pointer;list-style:none;font:400 11px var(--osMono);letter-spacing:.04em;
  text-transform:uppercase;color:var(--faint)}
.osApp .osTech>summary::-webkit-details-marker{display:none}
.osApp .osTech>summary::after{content:' ▾';color:var(--faint)}
.osApp .osTech[open]>summary::after{content:' ▴'}
.osApp .osTech>summary:hover{color:var(--muted)}
.osApp .osTechIn{display:flex;flex-direction:column;gap:10px;margin-top:10px}
/* ⚠ An id is for pasting into a terminal, so it is selectable and it wraps
   rather than being clipped — a truncated id is a wrong id. */
.osApp .osTech .val.id{
  font-size:11.5px;color:var(--muted);user-select:all;word-break:break-all}
.osApp .osTech .osAppNote{margin-top:0}

/* ── the facts under the fields ───────────────────────────────────────────── */
/* ⚠ SMALL AND GREY ON PURPOSE. Strength, rotation, who else can open it and the
   reveal log are what you check occasionally; the credential is what you came
   for. Drawn at the same weight as the fields they would compete with it. */
.osApp .osMeta{border-top:1px solid var(--line);padding-top:12px;display:flex;
  flex-direction:column;gap:6px}
.osApp .osMeta h3{
  margin:0 0 2px;font:400 11px var(--osMono);letter-spacing:.04em;
  text-transform:uppercase;color:var(--faint)}
.osApp .osMeta .mRow{display:flex;gap:10px;align-items:baseline;font-size:12.5px;line-height:1.45}
.osApp .osMeta .mRow .k{flex:none;min-width:112px;color:var(--muted)}
.osApp .osMeta .mRow .v{color:var(--ink);min-width:0;overflow-wrap:anywhere}

.osApp .osWho{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.osApp .osWho li{display:flex;gap:8px;align-items:baseline;font-size:12.5px}
.osApp .osWho .n{color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.osApp .osWho .r{font:400 11px var(--osMono);color:var(--faint)}
.osApp .osWho .c{margin-left:auto;font:400 11px var(--osMono);color:var(--faint)}
/* ⚡ A revoked colleague is kept and dimmed, never dropped — what they read is
   still what it was until somebody rotates it. */
.osApp .osWho li.gone{opacity:.55}
.osApp .osWho .x{font:400 10.5px var(--osMono);color:var(--amber);
  border:1px solid color-mix(in srgb,var(--amber) 40%,var(--line));border-radius:999px;padding:1px 7px}

.osApp .osLog{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;
  max-height:210px;overflow:auto}
.osApp .osLog li{display:flex;gap:8px;align-items:baseline;font-size:12px;line-height:1.4}
.osApp .osLog .w{color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.osApp .osLog .f{font:400 11px var(--osMono);color:var(--muted)}
.osApp .osLog .t{margin-left:auto;flex:none;font:400 11px var(--osMono);color:var(--faint)}
.osApp .osLog .p{font-size:11px;color:var(--faint)}

/* ── keep or replace ──────────────────────────────────────────────────────── */
/* ⛔ A LOCKED FIELD HAS NO INPUT AT ALL — that is what makes "leave it alone"
   true rather than promised. It reads as a field in a state, not as one that
   lost its contents, which is exactly what the empty box used to read as. */
.osApp .osKeep{display:flex;align-items:center;gap:9px;min-height:40px;
  padding:7px 8px 7px 12px;border:1px dashed var(--line2);border-radius:10px;background:var(--surf)}
.osApp .osKeep .v{flex:1;min-width:0;font:400 12.5px var(--osMono);color:var(--faint)}
.osApp .osKeep .a{display:flex;gap:6px;flex:none}
.osApp .osKeep button{padding:5px 12px;border:1px solid var(--line);border-radius:999px;
  background:var(--bg);color:var(--muted);font-size:12px;cursor:pointer;white-space:nowrap}
.osApp .osKeep button:hover{color:var(--ink);border-color:var(--line2)}
.osApp .osKeepOn{display:flex;gap:7px;align-items:center}
.osApp .osKeepOn input{flex:1;min-width:0}
.osApp .osKeepOn .undo{flex:none;padding:7px 12px;border:1px solid var(--line);border-radius:999px;
  background:transparent;color:var(--muted);font-size:12px;cursor:pointer;white-space:nowrap}
.osApp .osKeepOn .undo:hover{color:var(--ink);border-color:var(--line2)}

/* ⛔ A SLUG IS NOT A NAME. When a workspace record carries no name the header
   still has to say which workspace it is showing, so it prints the identifier
   — and dresses it as one: mono, quiet, in the tint the rest of this app uses
   for machine text. A person reading it can tell at a glance that this is the
   system's handle for their company, not their company's name. */
.osApp[data-app="passwords"] .rhSub .osVaultSlug{
  font:400 11.5px/1.45 var(--osMono);color:var(--faint);
  border:1px solid var(--line);border-radius:6px;padding:1px 7px}
