/* ============================================================================
   nb-kit.css — No Bug OS shared style kit
   v1 · 2026-07-17 · extracted VERBATIM from nobug-closeout (the canon surface)
   ----------------------------------------------------------------------------
   WHAT THIS IS
     The foundation every operator surface stands on, in the order that matters:
       1. field   (html/body)    — glass only reads as glass against the field
       2. frame   (.layout)      — fixed cockpit, columns scroll internally
       3. tokens  (:root)        — the whole token set, one definition
       4. components             — .qcard, doc-pane trio, .chip, .btn, .tag
       5. type                   — --t-* scale, 13px floor, no monospace

   WHAT THIS IS NOT
     Not a redesign. Every rule here is byte-for-byte what Closeout already
     ships. Linking this into Closeout is a no-op. Linking it into any other
     surface is the port.

   HOW TO USE
     In <head>, BEFORE the surface's own <style>:
       <link rel="stylesheet" href="https://os.nobugpest.com/__shell/kit.css">
     Then DELETE the surface's duplicated :root / field / frame / chrome and
     let the kit show through. The surface's <style> keeps only what is
     genuinely local to that surface, and overrides the kit by cascade order.

   RULES THIS FILE ENFORCES (operator rulings — do not relitigate)
     - No font under 13px. Every font-size goes through a --t-* token.
     - No monospace. --font-mono is ALIASED to the sans stack so it cannot be
       reintroduced by accident. tabular-nums aligns money, not the mono face.
     - Rust #C41A1A is a BRAND MARK. Never a control. Primary = graphite.
       Interactive/active = iOS blue #007AFF.
     - Nothing may paint flat var(--paper) as a background. It punches a hole
       in the field. (--paper survives only for legacy inputs/insets.)
     - [hidden]{display:none!important} — display:grid/flex defeats the attr.

   KNOWN DIVERGENCE (carried forward deliberately, do not "fix" here)
     .tag uses the FLAT tone tints (--danger-tint / --warn-tint / --go-tint)
     while .ms-doc-status uses the GLASS tints. That is Closeout as it stands
     today. Reconciling it is a change to the canon, not to the extraction —
     it belongs in a kit v2 that ships to every surface at once.
   ========================================================================== */


/* ============================================================
   3. TOKENS
   ============================================================ */
:root{
  --font-sans:-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;
  /* aliased to sans 2026-07-17 — hard rule: no monospace. tabular-nums aligns money, not mono. */
  --font-mono:-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif;

  --paper:#F8F8F8;
  --surface:rgba(255,255,255,0.88);
  --surface-2:rgba(246,246,248,0.80);
  --surface-3:rgba(235,235,240,0.70);
  --line:rgba(60,60,67,0.11);
  --line-2:rgba(60,60,67,0.07);

  --ink:#000;
  --ink-2:rgba(60,60,67,0.60);
  --ink-3:rgba(60,60,67,0.52);

  --rust:#C41A1A;
  --rust-deep:#A81212;
  --rust-tint:#FDEEED;
  /* Hard rule 4 (2026-07-17): rust is a brand mark only. Primary buttons are
     graphite; interactive/active states are iOS blue. Never rust on a control. */
  --btn-primary-bg:linear-gradient(180deg,#2C2C2E,#0F0F11);
  --btn-primary-bg-hover:linear-gradient(180deg,#3A3A3C,#1C1C1E);

  --danger:#D6362A;
  --danger-tint:#FEF0EF;
  --warn:#C25F00;
  --warn-tint:#FEF3E8;
  --go:#28A84C;
  --go-tint:#E6F7EE;
  --neutral:#8E8E93;
  --neutral-tint:#F5F5F5;

  --dark:#1C1C1E;
  --dark-ink:#FFF;

  --r-sm:10px;
  --r-md:13px;
  --r-lg:16px;
  --r-xl:20px;
  --r-2xl:26px;
  --r-pill:999px;

  --shadow-sm:0 1px 1px rgba(0,0,0,0.04),0 0 0 0.5px rgba(60,60,67,0.06);
  --shadow-md:0 2px 4px rgba(0,0,0,0.05),0 8px 20px rgba(0,0,0,0.07),0 0 0 0.5px rgba(60,60,67,0.05);
  --shadow-lg:0 4px 8px rgba(0,0,0,0.06),0 16px 36px rgba(0,0,0,0.10),0 0 0 0.5px rgba(60,60,67,0.04);

  /* 5. TYPE — the floor IS the rule. Nothing below --t-footnote/-label/-xs (13px). */
  --t-metric:52px;
  --t-display:34px;
  --t-h1:28px;
  --t-h2:22px;
  --t-h3:17px;
  --t-body:17px;
  --t-callout:16px;
  --t-sm:15px;
  --t-footnote:13px;
  --t-label:13px;
  --t-xs:13px;

  /* Liquid glass — matched to WO Pool tokens.
     --glass-hi is the inset top-edge highlight. It is what makes a surface read
     as LIT rather than flat. If a ported surface looks heavy, count these first. */
  --glass-blur:blur(20px) saturate(180%);
  --glass-blur-strong:blur(28px) saturate(200%);
  --glass-tint:rgba(255,255,255,0.55);
  --glass-tint-2:rgba(255,255,255,0.72);
  --glass-line:rgba(60,60,67,0.10);
  --glass-line-2:rgba(60,60,67,0.06);
  --glass-hi:inset 0 1px 0 rgba(255,255,255,0.65);
  --glass-shadow:0 1px 2px rgba(0,0,0,0.04),0 4px 12px rgba(0,0,0,0.06);
  --glass-shadow-lift:0 1px 3px rgba(0,0,0,0.06),0 8px 20px rgba(0,0,0,0.08);
  --glass-go-tint:rgba(42,145,72,0.10);
  --glass-go-line:rgba(42,145,72,0.22);
  --glass-go-ink:#1F6B33;
  --glass-warn-tint:rgba(194,95,0,0.09);
  --glass-warn-line:rgba(194,95,0,0.22);
  --glass-warn-ink:#8C4400;
  --glass-blue-tint:rgba(0,122,255,0.10);
  --glass-blue-line:rgba(0,122,255,0.22);
  --glass-blue-ink:#0066CC;
  --glass-rust-tint:rgba(168,48,42,0.10);
  --glass-rust-line:rgba(168,48,42,0.20);

  /* Doc-pane tones — three tones and a hairline. Named here for the first time.
     They were literals in Closeout; naming them is the only edit in this file,
     and the literals are preserved below so the render is identical. */
  --doc-header-bg:rgba(255,255,255,0.75);
  --doc-col-bg:rgba(242,242,245,0.55);
  --doc-stage-bg:rgba(232,232,238,0.55);
  --rail-bg:rgba(255,255,255,0.50);
  --chrome-bg:rgba(237,238,240,0.78);
}


/* ============================================================
   1. THE FIELD  — copy verbatim; nothing may paint flat --paper over it
   ============================================================ */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;padding:0;height:100%;
  background:#EEF0F3;
  background-image:
    radial-gradient(ellipse 800px 600px at 20% 0%, rgba(168,48,42,0.04) 0%, transparent 50%),
    radial-gradient(ellipse 700px 500px at 90% 100%, rgba(0,122,255,0.05) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 0%, rgba(255,255,255,0.55) 0%, transparent 60%);
  background-attachment:fixed;
  color:var(--ink);font-family:var(--font-sans);font-size:var(--t-body);line-height:1.47;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
body{overflow:hidden}

/* GEOMETRY WARNING. The rust wash sits at 20% 0%. In Closeout it lands inside
   506px of chrome (.nav-rail 56 + .ms-col-a 450). If your surface's rail is
   narrower, the wash clears it and lands on your first content card as a pink
   smear. Content columns are NOT transparent — see --doc-col-bg / --rail-bg.
   Only the bare .main wrapper is. */

button{font-family:inherit;font-size:inherit;cursor:pointer;border:none;background:none;color:inherit}
button:disabled{cursor:not-allowed}
a{color:var(--glass-blue-ink);text-decoration:none}@media(hover:hover){a:hover{text-decoration:underline}}
input,textarea,select{font-family:inherit;font-size:inherit;color:var(--ink)}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(60,60,67,0.18);border-radius:3px}@media(hover:hover){::-webkit-scrollbar-thumb:hover{background:rgba(60,60,67,0.30)}}


/* ============================================================
   PIN GATE
   ============================================================ */
.pin-screen{position:fixed;inset:0;display:grid;place-items:center;z-index:100;padding:24px}

/* ---- Gate card sizing (2026-07-17) -------------------------------------
   The subtitle is two lines by contract:
       line 1  "<Surface> — <what it does>"     <= 34 characters
       line 2  "Enter your operator PIN"
   440px card - 72px padding = 368px of text. At --t-sm (15px system) the
   average advance is ~7.3px, so 34ch ~= 248px — fits with room, and still
   fits a 390px phone once the mobile padding kicks in.
   EXCEEDING 34 CHARACTERS WRAPS THE DESCRIPTOR MID-PHRASE.
   ------------------------------------------------------------------------ */
.pin-card{background:rgba(255,255,255,0.82);border-radius:24px;padding:40px 36px;box-shadow:var(--shadow-lg);width:min(440px,92vw);text-align:center;border:0.5px solid rgba(60,60,67,0.08);-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px)}
.pin-logo{width:64px;height:64px;border-radius:14px;background:var(--rust);color:#fff;display:grid;place-items:center;font-weight:800;font-size:24px;margin:0 auto 20px}
.pin-card h1{font-size:var(--t-h2);font-weight:700;margin:0 0 8px}
.pin-card p{font-size:var(--t-sm);color:var(--ink-2);margin:0 0 24px;line-height:1.5}
.pin-input{width:100%;font-family:var(--font-sans);font-size:24px;letter-spacing:6px;text-align:center;padding:14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2);outline:none;margin-bottom:16px}
.pin-input:focus{border-color:var(--ink);background:var(--surface)}
.pin-submit{width:100%;padding:14px;background:var(--btn-primary-bg);color:#fff;font-weight:600;border-radius:var(--r-md);font-size:var(--t-callout)}@media(hover:hover){.pin-submit:hover:not(:disabled){background:var(--btn-primary-bg-hover)}}
.pin-error{color:var(--danger);font-size:var(--t-footnote);min-height:18px;margin-top:8px}


/* ============================================================
   HEADER CHROME
   Markup contract — exact, every surface, no slash:
     <div class="nb-squircle">NB</div>
     <div class="crumb"><span class="sep">No Bug</span> <b>Surface Name</b>
          <span class="hd-desc">— What it answers?</span></div>
     <div class="header-spacer"></div>
     <span class="header-date"></span>
     <span class="live-badge"><span class="live-dot"></span>LIVE</span>
     <button class="icon-btn" title="Refresh">…</button>
     <button class="icon-btn" title="Sign out">…</button>
     <div class="avatar">NK</div>
   Every icon button must be WIRED. A rendered control that does nothing is
   the same lie as a badge that says HOSTED.

   saturate(200%) is what pulls the field's colour up through the chrome.
   --glass-blur-strong alone does not do this, and an APPENDED backdrop-filter
   silently downgrades it. Do not "simplify" this line.
   ============================================================ */
.header{display:flex;align-items:center;gap:14px;padding:11px 20px;background:var(--chrome-bg);border-bottom:1px solid rgba(60,60,67,0.07);position:sticky;top:0;z-index:50;-webkit-backdrop-filter:saturate(200%) blur(28px);backdrop-filter:saturate(200%) blur(28px)}
.nb-squircle{width:36px;height:36px;border-radius:9px;background:var(--rust);color:#fff;display:grid;place-items:center;font-weight:800;font-size:14px;flex-shrink:0}
.crumb{display:flex;align-items:baseline;gap:8px;font-size:var(--t-sm);color:var(--ink-2);min-width:0}
.crumb b{color:var(--ink);font-weight:600}
.crumb .sep{color:var(--ink-3)}
.hd-desc{font-size:var(--t-footnote);color:var(--ink-3);margin-left:4px;white-space:nowrap}
.header-spacer{flex:1}
.live-badge{display:inline-flex;align-items:center;gap:6px;padding:5px 10px 5px 8px;background:var(--go-tint);color:var(--go);border-radius:var(--r-pill);font-family:var(--font-sans);font-size:var(--t-xs);font-weight:600;letter-spacing:0.05em}
.live-dot{width:7px;height:7px;border-radius:50%;background:var(--go);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.5}}
.header-date{font-family:var(--font-sans);font-size:var(--t-footnote);color:var(--ink-2)}
.icon-btn{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;color:var(--ink-2)}@media(hover:hover){.icon-btn:hover{background:var(--surface-2);color:var(--ink)}}
.header-back{flex-shrink:0;color:var(--ink)}
.header-back[hidden]{display:none!important}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--ink);color:#fff;display:grid;place-items:center;font-weight:600;font-size:var(--t-xs)}


/* ============================================================
   2. THE FRAME
   Full-height flex. body{overflow:hidden}. Columns scroll INTERNALLY.
   A scrolling page cannot hold a fixed document stage.
   ============================================================ */
.layout{display:flex;flex-direction:row;flex:1 1 auto;min-height:0;overflow:hidden}
.main{flex:1 1 auto;min-width:0;min-height:0;overflow:hidden;display:flex;flex-direction:column;background:transparent}

/* Primary left rail — 450px. Pin this width; the rust wash geometry depends on it. */
.ms-col-a{
  flex:0 0 450px;
  border-right:1px solid var(--glass-line);
  display:flex;flex-direction:column;overflow:hidden;
  background:var(--rail-bg);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
}
.ms-col-a-inner{flex:1 1 auto;overflow-y:auto;padding:20px 20px 40px}


/* ============================================================
   4. COMPONENTS
   ============================================================ */

/* ---- .qcard — the card/row primitive.
   NOT a white box with a drop shadow. If you find var(--shadow-md) on a
   container, that is the tell you are still shipping floating cards. ---- */
.qcard{
  position:relative;
  background:var(--glass-tint-2);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  border-radius:var(--r-lg);
  padding:16px 16px 16px 21px;
  overflow:hidden;
  border:1px solid var(--glass-line);
  box-shadow:var(--glass-shadow),var(--glass-hi);
  transition:background .15s,box-shadow .15s,transform .1s;
  cursor:pointer;
}@media(hover:hover){.qcard:hover{background:rgba(255,255,255,0.85);box-shadow:var(--glass-shadow-lift),var(--glass-hi)}}
.qcard:active{transform:scale(.998)}
.qcard.selected{background:rgba(255,255,255,0.88);border-color:var(--glass-rust-line);box-shadow:0 0 0 2px var(--glass-rust-line),var(--glass-shadow-lift),var(--glass-hi)}
.qcard.selected .edge{width:7px}
.qcard .edge{position:absolute;left:0;top:0;bottom:0;width:5px}

.qcard-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:4px;flex-wrap:wrap}
.qcard-id{font-family:var(--font-sans);font-size:var(--t-xs);color:var(--ink-2);font-weight:600}
.qcard-age{font-family:var(--font-sans);font-size:var(--t-xs);color:var(--ink-3);font-weight:500}
/* The row title is --t-h3 17/700. Map SEMANTICALLY. Do not map an old 14.5px
   to "nearest token" — that ships every row title two steps light. */
.qcard-address{font-size:var(--t-h3);font-weight:700;line-height:1.2}
.qcard-apt{font-weight:600;color:var(--ink-2);margin-left:4px}
.qcard-tags{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 10px}
.qcard-bottom{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap}
.qcard-bottom-left{display:flex;align-items:center;gap:9px;flex:1;min-width:0}
.qcard-pm{font-size:var(--t-xs);color:var(--ink-2)}
.qcard-amount{font-size:var(--t-h3);font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-0.01em}
/* Amber "no number" over a wrong number. A wrong number is worse than none. */
.qcard-amount-missing{color:var(--warn);font-size:var(--t-sm);font-weight:600;letter-spacing:0;text-transform:none}

/* ---- .tag — status pill on a row ---- */
.tag{display:inline-flex;align-items:center;gap:6px;padding:3px 9px;border-radius:var(--r-pill);background:var(--neutral-tint);color:var(--ink);font-size:var(--t-xs);font-weight:600}
.tag.tone-danger{background:var(--danger-tint);color:var(--danger)}
.tag.tone-warn{background:var(--warn-tint);color:var(--warn)}
.tag.tone-go{background:var(--go-tint);color:var(--go)}
.tag .dot{width:5px;height:5px;border-radius:50%;background:currentColor}

/* ---- .chip — the segmented / filter control. Active is iOS BLUE, never rust. ---- */
.chip{
  display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:var(--r-pill);
  background:var(--glass-tint);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-line);
  font-weight:600;font-size:var(--t-xs);color:var(--ink);
  box-shadow:var(--glass-shadow),var(--glass-hi);
  transition:background .12s,color .12s;cursor:pointer;
}@media(hover:hover){.chip:hover:not(.active){background:var(--glass-tint-2)}}
.chip.active{background:var(--glass-blue-tint);color:var(--glass-blue-ink);border-color:var(--glass-blue-line);box-shadow:0 0 0 1px var(--glass-blue-line),var(--glass-shadow),var(--glass-hi)}
.chip-count{font-family:var(--font-sans);font-size:var(--t-xs);padding:2px 6px;border-radius:var(--r-pill);background:var(--neutral-tint);color:var(--ink-2);min-width:20px;text-align:center}
.chip.active .chip-count{background:rgba(0,122,255,0.15);color:#007AFF}
.chip-row{display:flex;flex-wrap:wrap;gap:5px}

/* ---- .btn — one button vocabulary. Primary is GRAPHITE. ---- */
.btn{padding:8px 14px;border-radius:var(--r-sm);font-weight:600;font-size:var(--t-xs);display:inline-flex;align-items:center;justify-content:center;gap:6px;transition:all 0.15s;white-space:nowrap;cursor:pointer;border:none}
.btn:disabled{cursor:not-allowed;opacity:.5}
.btn-primary{background:var(--btn-primary-bg);color:#fff}@media(hover:hover){.btn-primary:hover:not(:disabled){background:var(--btn-primary-bg-hover)}}
.btn-secondary{
  background:var(--glass-tint-2);color:var(--ink);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  border:1px solid var(--glass-line);
  box-shadow:var(--glass-shadow),var(--glass-hi);
}@media(hover:hover){.btn-secondary:hover:not(:disabled){background:rgba(255,255,255,0.90)}}
.btn-ghost{background:var(--glass-tint);color:var(--ink-2);border:1px solid var(--glass-line);box-shadow:var(--glass-hi)}@media(hover:hover){.btn-ghost:hover:not(:disabled){background:var(--glass-tint-2);color:var(--ink)}}
.btn-go{background:var(--go);color:#fff}@media(hover:hover){.btn-go:hover:not(:disabled){background:#1e8a3d}}
.btn-danger{background:var(--danger);color:#fff}@media(hover:hover){.btn-danger:hover:not(:disabled){background:#a8281f}}
.btn-lg{padding:12px 18px;font-size:var(--t-footnote)}


/* ============================================================
   DOCUMENT PANES — three tones and a hairline. THEY ARE NOT CARDS.
     header  var(--doc-header-bg)  rgba(255,255,255,0.75)  <- the only white thing
     column  var(--doc-col-bg)     rgba(242,242,245,0.55)  <- no radius, no shadow
     stage   var(--doc-stage-bg)   rgba(232,232,238,0.55)  <- the page floats on it
     divider border-left: 1px solid var(--glass-line)
   The single most common porting failure is wrapping this in a card:
     background:var(--surface); border:1px solid var(--border);
     border-radius:var(--radius)  <- WRONG. That is card-on-field. Heavy.
   ============================================================ */
.ms-col-b.doc-col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;overflow:hidden;background:var(--doc-col-bg);border-left:1px solid var(--glass-line)}

/* Two rows: -top (title left, status + actions right) and -meta (label/value
   pairs). min-height:24px on -meta so sibling headers stay the same height. */
.ms-doc-header{
  flex:0 0 auto;
  padding:12px 16px 10px;
  border-bottom:1px solid var(--glass-line);
  background:var(--doc-header-bg);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  box-shadow:var(--glass-hi);
}
.ms-doc-header-top{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}
.ms-doc-header-meta{display:flex;align-items:center;gap:16px;flex-wrap:nowrap;overflow:hidden;margin-top:8px;min-height:24px}
.ms-doc-title{font-family:var(--font-sans);font-size:var(--t-label);font-weight:700;color:var(--ink-2);letter-spacing:.07em;text-transform:uppercase}
.ms-doc-meta-item{display:flex;align-items:baseline;gap:5px}
.ms-doc-meta-label{font-family:var(--font-sans);font-size:var(--t-label);font-weight:700;color:var(--ink-2);letter-spacing:.06em;text-transform:uppercase}
.ms-doc-meta-value{font-size:var(--t-sm);font-weight:600;color:var(--ink)}
.ms-doc-meta-value.go{color:var(--glass-go-ink)}
.ms-doc-meta-value.warn{color:var(--glass-warn-ink)}

.ms-doc-status{display:inline-flex;align-items:center;gap:4px;padding:4px 10px;border-radius:var(--r-pill);font-size:var(--t-xs);font-weight:700}
.ms-doc-status.ok{background:var(--glass-go-tint);color:var(--glass-go-ink);border:1px solid var(--glass-go-line)}
.ms-doc-status.missing{background:var(--glass-warn-tint);color:var(--glass-warn-ink);border:1px solid var(--glass-warn-line)}
.ms-doc-status.none{background:var(--glass-tint);color:var(--ink-2);border:1px solid var(--glass-line)}

.ms-doc-open{
  padding:6px 13px;border-radius:var(--r-sm);
  background:var(--glass-tint);border:1px solid var(--glass-line);
  -webkit-backdrop-filter:var(--glass-blur);backdrop-filter:var(--glass-blur);
  font-size:var(--t-xs);font-weight:600;color:var(--ink-2);text-decoration:none;flex-shrink:0;
  box-shadow:var(--glass-shadow),var(--glass-hi);
}@media(hover:hover){.ms-doc-open:hover{background:var(--glass-tint-2);color:var(--ink);text-decoration:none}}

/* The stage FLEXES to fill whatever remains after header/strips above and
   nav/notes/action bars below. No viewport math, no clipping. The PDF scrolls
   inside the embed. min-height floor keeps the doc usable on tiny windows.
   Use <object>, not <iframe>, for PDF embeds (Brave). Destroy and recreate the
   <object> element on URL change to force reload. */
.ms-doc-preview{flex:1 1 0;min-height:240px;overflow:hidden;background:rgba(235,235,240,0.50);position:relative;border-bottom:1px solid var(--glass-line)}
.ms-doc-stage{flex:1 1 0;min-height:240px;overflow:hidden;background:var(--doc-stage-bg);position:relative}
.ms-doc-preview iframe,.ms-doc-stage iframe,.ms-doc-stage object{position:absolute;inset:0;width:100%;height:100%;border:none;display:block}
.ms-doc-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:24px;color:var(--ink-3)}


/* ============================================================
   MONEY
   tabular-nums is what aligns money columns. Mono was only ever a side effect.
   Every dollar figure on a ledger surface gets this, or the column drifts.
   ============================================================ */
.num,.money{font-variant-numeric:tabular-nums}


/* ============================================================
   HOVER-REVEALED CONTROLS
   opacity:0 is NOT pointer-events:none. An invisible element with layout is
   still a click target.
   ============================================================ */
.reveal{opacity:0;pointer-events:none;transition:opacity .12s}
@media(hover:hover){.reveal-host:hover .reveal{opacity:1;pointer-events:auto}}
