/* ===== Loan Ranger — design system ============================== */
:root{
  --red:#E11D24; --red-deep:#B5161C; --red-wash:#FDEEEF; --charcoal:#1C2433;
  --paper:#FFFFFF; --ground:#F7F9FB; --surface-2:#EEF1F5; --surface-3:#E2E7EE;
  --ink:#0E131C; --ink-2:#3C4556; --ink-muted:#565d7e; --ink-faint:#8A92A6;
  --rule:#E4E8EE; --rule-2:#CBD1DA;
  --ok:#1F7A4C; --ok-wash:#EAF5EF; --warn:#8A5A00; --warn-wash:#FDF3E0; --warn-fill:#D28E04;
  --src:#2B5C8A; --src-wash:#E9F1F8; --bad:#A62121; --bad-wash:#FBECEC;
  /* One typeface. Montserrat for headings against Inter for body was two
     voices, and JetBrains Mono on every small-caps label made the furniture
     look like a terminal. Mono is now kept for the one thing that is actually
     a code: the deal reference. */
  --head:"Plus Jakarta Sans","Helvetica Neue",Arial,sans-serif;
  --body:"Plus Jakarta Sans","Helvetica Neue",Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
  --sh:0 1px 2px rgba(14,19,28,.04),0 2px 8px rgba(14,19,28,.04);
  --lift:0 6px 16px rgba(14,19,28,.07),0 20px 48px rgba(14,19,28,.08);
  --sidebar:252px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --red:#FF5A61; --red-deep:#E11D24; --red-wash:#2C1416; --charcoal:#11151C;
  --paper:#171B22; --ground:#0D1016; --surface-2:#1E232C; --surface-3:#272D38;
  --ink:#F2F5F9; --ink-2:#C3CAD6; --ink-muted:#A3ABBF; --ink-faint:#79819A;
  --rule:#272D38; --rule-2:#3C4450;
  --ok:#5FC08C; --ok-wash:#132419; --warn:#D9A441; --warn-wash:#2A2113;
  --src:#7FB0DA; --src-wash:#141F2A; --bad:#E58282; --bad-wash:#2A1515;
  --sh:0 1px 2px rgba(0,0,0,.35); --lift:0 10px 34px rgba(0,0,0,.5);
}}
:root[data-theme="dark"]{
  --red:#FF5A61;--red-deep:#E11D24;--red-wash:#2C1416;--charcoal:#11151C;
  --paper:#171B22;--ground:#0D1016;--surface-2:#1E232C;--surface-3:#272D38;
  --ink:#F2F5F9;--ink-2:#C3CAD6;--ink-muted:#A3ABBF;--ink-faint:#79819A;
  --rule:#272D38;--rule-2:#3C4450;--ok:#5FC08C;--ok-wash:#132419;
  --warn:#D9A441;--warn-wash:#2A2113;--src:#7FB0DA;--src-wash:#141F2A;
  --bad:#E58282;--bad-wash:#2A1515;--sh:0 1px 2px rgba(0,0,0,.35);--lift:0 10px 34px rgba(0,0,0,.5);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--ground);color:var(--ink);font-family:var(--body);
  font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{margin:0;font-family:var(--head);font-weight:800;line-height:1.1;letter-spacing:-.03em;text-wrap:balance}
p{margin:0} a{color:inherit} button{font-family:var(--body);cursor:pointer}
:focus-visible{outline:2px solid var(--red);outline-offset:2px;border-radius:5px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
.lab{font-family:var(--body);font-weight:700;font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint)}
.num{font-variant-numeric:tabular-nums}
.muted{color:var(--ink-muted)}
.skip{position:absolute;left:-9999px;top:0;z-index:999;background:var(--red);color:#fff;padding:10px 16px;font-weight:700}
.skip:focus{left:0}

/* ── buttons ─────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--red);color:#fff;
  border:none;border-radius:7px;font-weight:700;font-size:14.5px;padding:11px 19px;text-decoration:none;
  box-shadow:0 1px 2px rgba(14,19,28,.08);transition:background .14s,transform .06s,box-shadow .14s;white-space:nowrap}
.btn:hover{background:var(--red-deep)} .btn:active{transform:translateY(1px);box-shadow:none}
.btn:disabled{background:var(--rule-2);color:var(--ink-faint);cursor:not-allowed;box-shadow:none}
.btn-o{background:var(--paper);color:var(--ink);border:1px solid var(--rule-2);box-shadow:none}
.btn-o:hover{background:var(--surface-2)}
.btn-ghost{background:transparent;color:var(--ink-muted);box-shadow:none}
.btn-ghost:hover{background:var(--surface-2);color:var(--ink)}
.btn-s{font-size:13px;padding:8px 14px} .btn-xs{font-size:12px;padding:6px 11px}
.btn-block{width:100%}

/* ── form ────────────────────────────── */
label{display:block;font-size:13px;font-weight:600;color:var(--ink-muted);margin-bottom:6px}
input[type=text],input[type=email],input[type=password],input[type=tel],input[type=number],
input[type=date],input[type=search],input[type=url],input[type=month],select,textarea{
  width:100%;font-family:var(--body);font-size:15px;padding:11px 14px;border:1px solid var(--rule-2);
  border-radius:7px;background:var(--paper);color:var(--ink);transition:border-color .14s,box-shadow .14s}
input:focus,select:focus,textarea:focus{border-color:var(--red);box-shadow:0 0 0 3px var(--red-wash);outline:none}
input[aria-invalid=true]{border-color:var(--bad)}
.field+.field{margin-top:15px}
.err{color:var(--bad);font-size:13px;margin-top:6px}
.hint{color:var(--ink-muted);font-size:13px;margin-top:6px}

/* ── surfaces ────────────────────────── */
.card{background:var(--paper);border:1px solid var(--rule);border-radius:11px;box-shadow:var(--sh);overflow:hidden}
.card+.card{margin-top:16px}
.card-h{padding:16px 20px;border-bottom:1px solid var(--rule);background:var(--surface-2);
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.card-h h2,.card-h h3{font-size:15.5px;letter-spacing:-.02em}
.card-h p{font-size:12.5px;color:var(--ink-muted);margin-top:3px;width:100%}
.card-b{padding:20px}
.card-f{padding:14px 20px;border-top:1px solid var(--rule);background:var(--surface-2);display:flex;gap:9px;flex-wrap:wrap}
.spacer{margin-left:auto}

/* ── table ───────────────────────────── */
table{width:100%;border-collapse:collapse;font-size:14px}
th{font-family:var(--body);font-weight:700;font-size:10.5px;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-faint);
  text-align:left;padding:11px 20px;background:var(--surface-2);font-weight:500;border-bottom:1px solid var(--rule-2)}
td{padding:13px 20px;border-bottom:1px solid var(--rule);vertical-align:middle}
tbody tr:last-child td{border-bottom:none}
tbody tr{transition:background .1s}
tbody tr.row-link:hover{background:var(--surface-2);cursor:pointer}
.rowname{display:inline-block;font-weight:700;font-size:14.5px;color:var(--ink);text-decoration:none}
.rowname:hover{color:var(--red);text-decoration:underline;text-underline-offset:3px}
tr.row-link:hover .rowname{color:var(--red)}
td.r,th.r{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}

/* ── chips / badges ──────────────────── */
.chip{display:inline-flex;align-items:center;gap:5px;font-family:var(--body);font-size:10.5px;letter-spacing:.04em;
  text-transform:uppercase;font-weight:600;padding:4px 9px;border-radius:999px;white-space:nowrap}
.c-ok{background:var(--ok-wash);color:var(--ok)} .c-warn{background:var(--warn-wash);color:var(--warn)}
.c-src{background:var(--src-wash);color:var(--src)} .c-bad{background:var(--bad-wash);color:var(--bad)}
.c-mute{background:var(--surface-3);color:var(--ink-muted)}
.c-red{background:var(--red);color:#fff}

/* ── callouts ────────────────────────── */
.note,.good,.alert,.info{border:1px solid;border-left-width:3px;border-radius:9px;padding:15px 18px;
  font-size:14px;line-height:1.6;color:var(--ink-2)}
.info{background:var(--src-wash);border-color:var(--src)} .good{background:var(--ok-wash);border-color:var(--ok)}
.alert{background:var(--warn-wash);border-color:var(--warn)} .note{background:var(--surface-2);border-color:var(--rule-2)}
.info h4{color:var(--src)} .good h4{color:var(--ok)} .alert h4{color:var(--warn)}
.note h4,.info h4,.good h4,.alert h4{font-size:14px;margin-bottom:5px}

/* ── empty state ─────────────────────── */
.empty{padding:52px 24px;text-align:center;color:var(--ink-muted)}
.empty h3{font-size:16px;margin-bottom:7px;color:var(--ink)}
.empty p{font-size:14px;max-width:46ch;margin:0 auto}
.empty .btn{margin-top:20px}

/* ── app shell ───────────────────────── */
.shell{display:grid;grid-template-columns:var(--sidebar) 1fr;min-height:100vh}
@media (max-width:980px){.shell{grid-template-columns:1fr}}
/* The sidebar is charcoal. It was written that way originally, but the
   dark-theme overrides were scoped ":root:not([data-theme=light]) .side" with
   no media query around them, so they fired in daylight and the charcoal never
   rendered once. This is the real thing, as the default, with no attribute
   needed — and the white rail kept below under [data-rail="light"]. */
.side{background:var(--charcoal);color:#E6EAF1;border-right:1px solid rgba(255,255,255,.07);
  display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
@media (max-width:980px){.side{position:static;height:auto}}

.side-brand{display:flex;align-items:center;gap:11px;padding:19px 20px;
  border-bottom:1px solid rgba(255,255,255,.09);text-decoration:none}
.side-brand b{font-family:var(--head);font-weight:800;font-size:15px;letter-spacing:-.02em;color:#fff}
.side-brand b em{font-style:normal;color:#FF5A61}
.side-brand small{display:block;font-family:var(--body);font-weight:700;font-size:9px;letter-spacing:.2em;
  text-transform:uppercase;color:rgba(230,234,241,.52);margin-top:2px}
/* a span is inline by default, and width/height do nothing on an inline box —
   without display:block this collapses to 0x0 outside a flex container */
.lrm{display:block;width:32px;height:27px;flex:none;background:url(/img/lr-mark.png) center/contain no-repeat}
/* The mark is a red house beside a dark navy star. On charcoal the star
   disappears into the background, so the rail uses a copy with the star
   repainted white — same artwork, one colour swapped, red untouched. */
.side-brand .lrm{background-image:url(/img/lr-mark-light.png);
  filter:drop-shadow(0 2px 7px rgba(225,29,36,.35))}

.side-org{padding:14px 20px;border-bottom:1px solid rgba(255,255,255,.09);font-size:13px}
.side-org .lab{color:rgba(230,234,241,.55)}
.side-org b{display:block;font-weight:700;margin-top:3px;color:#fff}

.side-nav{padding:12px 10px;flex:1;overflow-y:auto}
.side-nav a{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:9px;
  text-decoration:none;font-size:14px;font-weight:700;color:rgba(230,234,241,.78);margin-bottom:2px}
.side-nav a:hover{background:rgba(255,255,255,.08);color:#fff}
/* The active item wins every contest with hover. It used to lose: the old
   light override carried more specificity than ".side-nav a.on:hover", so
   moving the mouse over the red pill turned it grey. */
.side-nav a.on,.side-nav a.on:hover,.side-nav a.on:focus{
  background:var(--red);color:#fff;box-shadow:0 2px 14px rgba(225,29,36,.45)}
.side-nav .grp{font-family:var(--body);font-weight:700;font-size:10px;letter-spacing:.13em;text-transform:uppercase;
  color:rgba(230,234,241,.46);padding:16px 12px 7px}

.side-foot{padding:14px 16px;border-top:1px solid rgba(255,255,255,.09);font-size:12.5px}
.side-foot a{color:inherit;text-decoration:none;opacity:.72}.side-foot a:hover{opacity:1}
.side-user{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.av{width:32px;height:32px;border-radius:50%;background:var(--red);color:#fff;display:grid;place-items:center;
  font-family:var(--head);font-weight:800;font-size:12px;flex:none}
.side-user .nm{font-weight:700;font-size:13px;line-height:1.3;color:#fff}
.side-user .rl{font-size:11.5px;color:rgba(230,234,241,.62);text-transform:capitalize}

.main{min-width:0;display:flex;flex-direction:column}
.topbar{background:var(--paper);border-bottom:1px solid var(--rule);padding:14px 26px;display:flex;
  align-items:center;gap:16px;flex-wrap:wrap;position:sticky;top:0;z-index:20}
.topbar h1{font-size:19px;letter-spacing:-.025em}
.topbar .sub{font-size:13px;color:var(--ink-muted);width:100%;margin-top:2px}
.content{padding:26px;max-width:1500px;width:100%}
.proto{background:var(--warn-wash);border-bottom:1px solid var(--warn);color:var(--warn);
  font-family:var(--body);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;padding:7px 26px;font-weight:700}

/* ── auth pages ──────────────────────── */
.auth{min-height:100vh;display:grid;place-items:center;padding:40px 22px;background:var(--ground)}
.auth-box{width:100%;max-width:412px}
.auth-top{text-align:center;margin-bottom:24px}
.auth-top .lrm{margin:0 auto 14px}
.auth-top h1{font-size:1.5rem}
.auth-top p{color:var(--ink-muted);font-size:14.5px;margin-top:8px}
.auth .card-b{padding:26px}
.auth-foot{text-align:center;margin-top:18px;font-size:13px;color:var(--ink-muted)}
.row{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px}
.chk{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink-muted)}
.chk input{width:16px;height:16px;accent-color:var(--red);margin:0}
.chk label{margin:0;font-weight:400}
.code-in{font-family:var(--mono);font-size:26px;letter-spacing:.42em;text-align:center;padding:14px}

/* ── stats ───────────────────────────── */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));gap:13px;margin-bottom:20px}
.stat{background:var(--paper);border:1px solid var(--rule);border-radius:11px;padding:17px 19px;box-shadow:var(--sh)}
.stat .v{font-family:var(--head);font-size:1.75rem;font-weight:800;letter-spacing:-.04em;margin-top:6px;font-variant-numeric:tabular-nums}
.stat .d{font-size:12.5px;color:var(--ink-muted);margin-top:3px}

/* ── progress ────────────────────────── */
.bar{height:6px;background:var(--surface-3);border-radius:3px;overflow:hidden;min-width:80px}
.bar i{display:block;height:100%;background:var(--ok);transition:width .3s ease}
.pips{display:flex;gap:3px}
.pips i{height:5px;width:22px;border-radius:3px;background:var(--surface-3)}
.pips i.on{background:var(--ok)} .pips i.now{background:var(--red)}

/* ── doc checklist ───────────────────── */
.doc{display:flex;align-items:center;gap:14px;padding:15px 20px;border-bottom:1px solid var(--rule)}
.doc:last-child{border-bottom:none}
.doc .ic{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:none;font-size:15px;
  background:var(--surface-3);color:var(--ink-faint)}
.doc.ok .ic{background:var(--ok-wash);color:var(--ok)}
.doc.rej .ic{background:var(--bad-wash);color:var(--bad)}
.doc .nm{flex:1;min-width:0}
.doc .nm b{font-weight:600;font-size:14.5px;display:block}
.doc .nm small{color:var(--ink-muted);font-size:12.5px}
.doc .act{display:flex;gap:7px;align-items:center;flex-wrap:wrap}

/* ── dialog ──────────────────────────── */
.dlg-wrap{position:fixed;inset:0;background:rgba(14,19,28,.5);backdrop-filter:blur(3px);display:grid;
  place-items:center;z-index:999;padding:22px}
.dlg{background:var(--paper);border:1px solid var(--rule);border-radius:12px;box-shadow:0 20px 60px rgba(14,19,28,.3);
  max-width:460px;width:100%;overflow:hidden}
.dlg-h{padding:20px 22px 0}.dlg-h h3{font-size:16.5px}
.dlg-b{padding:11px 22px 20px;font-size:14px;color:var(--ink-muted);line-height:1.6}
.dlg-f{padding:14px 22px;background:var(--surface-2);border-top:1px solid var(--rule);display:flex;justify-content:flex-end;gap:9px}

/* ── the sign-in screen ──────────────────────────────────────── */
.auth{position:relative;overflow:hidden}
.auth::before{content:"";position:absolute;left:50%;top:14%;translate:-50% 0;
  width:min(760px,150vw);height:460px;pointer-events:none;z-index:0;
  background:radial-gradient(42% 46% at 50% 50%,var(--red-wash) 0%,transparent 72%)}
.auth-box{position:relative;z-index:1}
.auth-top .lrm{width:62px;height:52px;position:relative}

@media (prefers-reduced-motion:no-preference){
  /* the mark lands first, with weight */
  .auth-top .lrm{animation:markIn .78s cubic-bezier(.2,1.1,.32,1) both}
  /* a slow halo breathing behind it, so the page is never quite still */
  .auth-top{position:relative}
  .auth-top::before{content:"";position:absolute;left:50%;top:4px;translate:-50% 0;
    width:120px;height:120px;border-radius:50%;z-index:-1;
    background:radial-gradient(circle,var(--red-wash) 0%,transparent 68%);
    animation:halo 5.5s ease-in-out infinite}
  .auth-top h1{animation:riseIn .62s cubic-bezier(.22,.8,.3,1) .16s both}
  .auth-top p {animation:riseIn .62s cubic-bezier(.22,.8,.3,1) .24s both}
  .auth .card{animation:cardIn .7s cubic-bezier(.22,.8,.3,1) .3s both}
  .auth-foot{animation:riseIn .6s cubic-bezier(.22,.8,.3,1) .5s both}
  .auth .field{animation:riseIn .5s cubic-bezier(.22,.8,.3,1) both}
  .auth .field:nth-of-type(1){animation-delay:.42s}
  .auth .field:nth-of-type(2){animation-delay:.5s}
  .auth .btn-block{animation:riseIn .5s cubic-bezier(.22,.8,.3,1) .6s both}

  /* the button fills on hover rather than just changing colour */
  .btn-block{position:relative;overflow:hidden}
  .btn-block::after{content:"";position:absolute;inset:0;background:var(--red-deep);
    transform:scaleX(0);transform-origin:left;transition:transform .34s cubic-bezier(.22,.8,.3,1);z-index:0}
  .btn-block:hover::after{transform:scaleX(1)}
  .btn-block > *{position:relative;z-index:1}

  /* six digits land one at a time */
  .code-in{animation:riseIn .5s cubic-bezier(.22,.8,.3,1) .42s both}
}
@keyframes markIn{
  from{opacity:0;transform:translateY(-10px) scale(.72) rotate(-7deg)}
  to  {opacity:1;transform:none}
}
@keyframes halo{
  0%,100%{opacity:.55;transform:translate(-50%,0) scale(.94)}
  50%    {opacity:1;  transform:translate(-50%,0) scale(1.08)}
}
@keyframes riseIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes cardIn{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}

/* ═══════════════════════════════════════════════════════════════
   Polish layer — motion is purposeful: it shows hierarchy,
   confirms an action, or reveals state. Nothing moves for show.
   ═══════════════════════════════════════════════════════════════ */

/* a progress bar whenever Livewire is thinking */
.lr-progress{position:fixed;top:0;left:0;height:2px;width:0;z-index:9999;
  background:linear-gradient(90deg,var(--red),color-mix(in srgb,var(--red) 55%,#fff));
  box-shadow:0 0 10px color-mix(in srgb,var(--red) 55%,transparent);
  transition:width .25s ease,opacity .3s ease;opacity:0;pointer-events:none}
.lr-progress.on{opacity:1}

@media (prefers-reduced-motion:no-preference){

  /* ── the page arrives, it does not just appear ── */
  .content > *{animation:lrRise .5s cubic-bezier(.22,.8,.3,1) both}
  .content > *:nth-child(1){animation-delay:.02s}
  .content > *:nth-child(2){animation-delay:.08s}
  .content > *:nth-child(3){animation-delay:.14s}
  .content > *:nth-child(4){animation-delay:.2s}
  .content > *:nth-child(n+5){animation-delay:.24s}
  .stats .stat{animation:lrRise .5s cubic-bezier(.22,.8,.3,1) both}
  .stats .stat:nth-child(1){animation-delay:.04s}
  .stats .stat:nth-child(2){animation-delay:.1s}
  .stats .stat:nth-child(3){animation-delay:.16s}
  .stats .stat:nth-child(4){animation-delay:.22s}

  /* ── sidebar: the active item is anchored, not just coloured ── */
  .side-nav a{position:relative;overflow:hidden}
  .side-nav a::before{content:"";position:absolute;left:0;top:50%;translate:0 -50%;
    width:3px;height:0;border-radius:0 3px 3px 0;background:#fff;
    transition:height .26s cubic-bezier(.22,.8,.3,1)}
  .side-nav a.on::before{height:60%}
  .side-nav a:not(.on):hover{transform:translateX(2px)}
  .side-nav a{transition:background .16s ease,color .16s ease,transform .18s cubic-bezier(.22,.8,.3,1)}

  /* ── cards lift, and the border wakes up ── */
  .card{transition:box-shadow .22s ease,border-color .22s ease,transform .22s cubic-bezier(.22,.8,.3,1)}
  .card:hover{box-shadow:var(--lift);border-color:var(--rule-2)}
  .stat{transition:box-shadow .22s ease,transform .22s cubic-bezier(.22,.8,.3,1),border-color .22s ease}
  .stat:hover{transform:translateY(-2px);box-shadow:var(--lift);border-color:var(--rule-2)}

  /* ── rows answer the cursor ── */
  tbody tr.row-link{transition:background .14s ease,box-shadow .18s ease}
  tbody tr.row-link:hover{box-shadow:inset 3px 0 0 var(--red)}

  /* ── buttons fill rather than flicker ── */
  .btn:not(.btn-o):not(.btn-ghost){position:relative;overflow:hidden;isolation:isolate}
  .btn:not(.btn-o):not(.btn-ghost)::after{content:"";position:absolute;inset:0;z-index:-1;
    background:var(--red-deep);transform:scaleX(0);transform-origin:left;
    transition:transform .3s cubic-bezier(.22,.8,.3,1)}
  .btn:not(.btn-o):not(.btn-ghost):hover::after{transform:scaleX(1)}
  .btn-o,.btn-ghost{transition:background .16s ease,border-color .16s ease,color .16s ease}

  /* ── the document list reveals in order ── */
  .doc{transition:background .16s ease}
  .doc:hover{background:var(--surface-2)}

  /* ── progress bars grow into place ── */
  .bar i{transition:width .6s cubic-bezier(.22,.8,.3,1)}
  .pips i{transition:background .3s ease}

  /* ── chips settle in ── */
  .chip{transition:transform .16s ease}
  .card-h .chip:hover{transform:translateY(-1px)}

  /* ── inputs ── */
  input,select,textarea{transition:border-color .16s ease,box-shadow .16s ease,background .16s ease}

  /* ── anything Livewire is working on dims politely ── */
  [wire\:loading]{transition:opacity .2s ease}
}

@keyframes lrRise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

/* the empty state should feel considered, not like a dead end */
.empty{position:relative}
.empty::before{content:"";position:absolute;left:50%;top:38%;translate:-50% -50%;
  width:170px;height:170px;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,var(--surface-2) 0%,transparent 70%)}
.empty > *{position:relative}

/* the topbar gains a hairline as you scroll under it */
.topbar{transition:box-shadow .2s ease}
.topbar.stuck{box-shadow:0 1px 0 var(--rule),0 6px 18px rgba(14,19,28,.05)}

/* ══ premium controls ══════════════════════════════════════════
   No native form furniture anywhere: search, file, colour, check. */

/* search — magnifier, no OS chrome, custom clear */
input[type=search]{
  -webkit-appearance:none;appearance:none;padding-left:37px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8f9e' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:13px 50%;background-size:15px 15px}
input[type=search]:focus{
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23E11D24' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.6-3.6'/%3E%3C/svg%3E")}
input[type=search]::-webkit-search-cancel-button,
input[type=search]::-webkit-search-decoration{-webkit-appearance:none;appearance:none}
input[type=search]::-webkit-search-cancel-button{
  height:15px;width:15px;cursor:pointer;opacity:.45;
  background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E") center/13px no-repeat}
input[type=search]::-webkit-search-cancel-button:hover{opacity:.9}

/* file — hidden input, branded surface, live filename */
.filefield{position:relative}
.filefield>input[type=file]{position:absolute;width:1px;height:1px;padding:0;margin:0;
  opacity:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.filefield>label{display:flex;align-items:stretch;margin:0;border:1px dashed var(--rule-2);
  border-radius:9px;background:var(--surface-2);overflow:hidden;cursor:pointer;font-weight:400;
  transition:border-color .16s ease,background .16s ease,box-shadow .16s ease}
.filefield>label:hover{border-color:var(--red);background:var(--red-wash)}
.filefield>input[type=file]:focus-visible+label{border-color:var(--red);
  box-shadow:0 0 0 3px var(--red-wash);border-style:solid}
.filefield .ff-btn{display:flex;align-items:center;gap:7px;flex:0 0 auto;padding:10px 15px;
  background:var(--ink);color:#fff;font-family:var(--body);font-size:13px;font-weight:600;
  letter-spacing:.01em;transition:background .16s ease}
.filefield>label:hover .ff-btn{background:var(--red)}
.filefield .ff-btn svg{width:14px;height:14px;flex:0 0 auto}
.filefield .ff-name{flex:1;min-width:0;display:flex;align-items:center;padding:0 14px;
  font-size:13.5px;color:var(--ink-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.filefield.has .ff-name{color:var(--ink);font-weight:600}
.filefield.sm>label{border-radius:8px}
.filefield.sm .ff-btn{padding:7px 12px;font-size:12px}
.filefield.sm .ff-name{padding:0 11px;font-size:12.5px}

/* colour — just a rounded swatch, no OS well */
.swatch{position:relative;flex:0 0 auto;width:46px;height:44px;border-radius:9px;overflow:hidden;
  border:1px solid var(--rule-2);box-shadow:var(--sh);cursor:pointer;
  transition:transform .14s ease,box-shadow .16s ease,border-color .16s ease}
.swatch:hover{transform:translateY(-1px);border-color:var(--rule-2);box-shadow:0 5px 14px rgba(17,19,26,.14)}
.swatch:focus-within{border-color:var(--red);box-shadow:0 0 0 3px var(--red-wash)}
.swatch input[type=color]{position:absolute;top:-8px;left:-8px;width:calc(100% + 16px);
  height:calc(100% + 16px);padding:0;margin:0;border:0;background:none;cursor:pointer;
  -webkit-appearance:none;appearance:none}
.swatch input[type=color]::-webkit-color-swatch-wrapper{padding:0;border:0}
.swatch input[type=color]::-webkit-color-swatch{border:0;border-radius:0}
.swatch input[type=color]::-moz-color-swatch{border:0}

/* checkbox — custom box and tick */
input[type=checkbox]{-webkit-appearance:none;appearance:none;flex:0 0 auto;
  width:18px;height:18px;margin:0;padding:0;border:1.5px solid var(--rule-2);border-radius:5px;
  background:var(--paper);cursor:pointer;position:relative;
  transition:background .15s ease,border-color .15s ease,box-shadow .15s ease}
input[type=checkbox]:hover{border-color:var(--red)}
input[type=checkbox]:checked{background:var(--red);border-color:var(--red)}
input[type=checkbox]:checked::after{content:"";position:absolute;left:5px;top:1.5px;
  width:4.5px;height:9px;border:solid #fff;border-width:0 2.1px 2.1px 0;transform:rotate(42deg)}
input[type=checkbox]:focus-visible{box-shadow:0 0 0 3px var(--red-wash);outline:none}
.chk input[type=checkbox]{width:18px;height:18px}

/* sidebar identity stacks properly */
.side-user .nm,.side-user .rl{display:block}
.side-user>span:last-child{min-width:0;overflow:hidden}
.side-user .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* select — our chevron, never the OS one */
select{-webkit-appearance:none;appearance:none;padding-right:38px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8f9e' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 13px center;background-size:15px 15px}
select:hover{border-color:var(--rule-2)}
select:focus{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23E11D24' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")}
select::-ms-expand{display:none}

/* a focus ring everywhere, for people who drive by keyboard */
a:focus-visible,button:focus-visible,[tabindex]:focus-visible{
  outline:2px solid var(--red);outline-offset:2px;border-radius:6px}

/* ── the sign-in lockup: mark plus name, as one thing ── */
.auth-mark{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:16px}
.auth-top .auth-mark .lrm{margin:0}
.auth-word{text-align:left}
.auth-word b{display:block;font-family:var(--head);font-weight:800;font-size:1.45rem;
  letter-spacing:-.03em;line-height:1;color:var(--ink)}
.auth-word b em{font-style:normal;color:var(--red)}
.auth-word small{display:block;font-family:var(--body);font-weight:700;font-size:9.5px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ink-muted);margin-top:5px}

@media (prefers-reduced-motion:no-preference){
  .auth-word{animation:riseIn .6s cubic-bezier(.22,.8,.3,1) .22s both}
}
@media (max-width:420px){
  .auth-mark{gap:11px}
  .auth-word b{font-size:1.2rem}
}

/* ══ life ══════════════════════════════════════════════════════════
   Motion that tells you something: what just arrived, what is working,
   what you are about to click. Nothing here moves for its own sake, and
   all of it is off for anyone who asked their machine to keep still. */

@media (prefers-reduced-motion:no-preference){

  /* ── the sidebar introduces itself, once ── */
  .side-brand .lrm{animation:markPop .7s cubic-bezier(.2,1.1,.32,1) both}
  .side-brand b,.side-brand small{animation:slideL .5s cubic-bezier(.22,.8,.3,1) .1s both}
  .side-org{animation:slideL .5s cubic-bezier(.22,.8,.3,1) .16s both}
  .side-nav a{animation:slideL .42s cubic-bezier(.22,.8,.3,1) both}
  .side-nav a:nth-of-type(1){animation-delay:.20s}
  .side-nav a:nth-of-type(2){animation-delay:.25s}
  .side-nav a:nth-of-type(3){animation-delay:.30s}
  .side-nav a:nth-of-type(4){animation-delay:.35s}
  .side-nav a:nth-of-type(n+5){animation-delay:.40s}
  .side-foot{animation:riseIn .5s cubic-bezier(.22,.8,.3,1) .46s both}

  /* the active pill catches the light once it has landed */
  .side-nav a.on{position:relative;overflow:hidden}
  .side-nav a.on::after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:45%;
    background:linear-gradient(100deg,transparent,rgba(255,255,255,.34),transparent);
    animation:sheen 2.6s cubic-bezier(.3,0,.2,1) .9s 1 both}
  .side-nav a{transition:background .16s ease,color .16s ease,transform .18s cubic-bezier(.22,.8,.3,1),
              box-shadow .2s ease}
  .side-nav a:not(.on):hover{transform:translateX(3px)}
  .side-nav a.on:hover{box-shadow:0 4px 16px rgba(225,29,36,.38)}

  /* ── the page title arrives with the page ── */
  .topbar h1{animation:slideL .5s cubic-bezier(.22,.8,.3,1) both}
  .topbar .sub{animation:slideL .5s cubic-bezier(.22,.8,.3,1) .07s both}

  /* ── figures count up, because a number that lands means something ── */
  .stat .v.lr-count,.lr-count{font-variant-numeric:tabular-nums}

  /* ── table rows arrive in order, not all at once ── */
  tbody tr{animation:rowIn .42s cubic-bezier(.22,.8,.3,1) both}
  tbody tr:nth-child(1){animation-delay:.26s} tbody tr:nth-child(2){animation-delay:.31s}
  tbody tr:nth-child(3){animation-delay:.36s} tbody tr:nth-child(4){animation-delay:.41s}
  tbody tr:nth-child(5){animation-delay:.46s} tbody tr:nth-child(6){animation-delay:.50s}
  tbody tr:nth-child(n+7){animation-delay:.54s}

  /* ── document and list rows, same idea ── */
  .doc{animation:rowIn .42s cubic-bezier(.22,.8,.3,1) both}
  .doc:nth-child(1){animation-delay:.28s} .doc:nth-child(2){animation-delay:.34s}
  .doc:nth-child(3){animation-delay:.40s} .doc:nth-child(4){animation-delay:.46s}
  .doc:nth-child(n+5){animation-delay:.50s}
  .doc{transition:background .16s ease}
  .doc:hover{background:var(--surface-2)}

  /* ── chips pop rather than appear ── */
  .chip{animation:chipIn .34s cubic-bezier(.2,1.2,.32,1) .44s both}

  /* ── a bar that fills is a bar you believe ── */
  .bar > span,.prog > span,.bar-fill{transform-origin:left;
    animation:growX .9s cubic-bezier(.22,.8,.3,1) .5s both}

  /* ── every button answers the press, not just the hover ── */
  .btn{transition:transform .12s cubic-bezier(.22,.8,.3,1),box-shadow .18s ease,background .16s ease}
  .btn:active{transform:translateY(1px) scale(.985)}

  /* ── something to say arrives from above ── */
  .good,.alert,.note{animation:dropIn .5s cubic-bezier(.2,1.05,.32,1) both}

  /* ── while Livewire is thinking, the thing it is changing says so ── */
  [wire\:loading].lr-busy,.lr-busy[wire-loading]{opacity:.55}
  .lr-working{position:relative;overflow:hidden}
  .lr-working::after{content:"";position:absolute;inset:0;pointer-events:none;
    background:linear-gradient(100deg,transparent 20%,rgba(225,29,36,.07) 50%,transparent 80%);
    background-size:220% 100%;animation:shimmer 1.1s linear infinite}
}

@keyframes markPop{from{opacity:0;transform:scale(.6) rotate(-14deg)}
  60%{opacity:1;transform:scale(1.08) rotate(3deg)} to{opacity:1;transform:none}}
@keyframes slideL{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
@keyframes rowIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes chipIn{from{opacity:0;transform:scale(.72)}to{opacity:1;transform:none}}
@keyframes growX{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes dropIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
@keyframes sheen{from{left:-60%}to{left:130%}}
@keyframes shimmer{from{background-position:120% 0}to{background-position:-120% 0}}

/* ══ cards and figures, premium ════════════════════════════════════
   A border alone is a box. These get an edge that catches light, a
   header that is not flat, and — where the number means something —
   a colour that says which way is good. */

.card{background:var(--paper);border:1px solid var(--rule);border-radius:14px;
  box-shadow:0 1px 2px rgba(14,19,28,.04),0 4px 14px rgba(14,19,28,.05);
  overflow:hidden;position:relative}
.card+.card{margin-top:18px}

/* a hairline of brand along the top edge, visible only as a sheen */
.card::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(225,29,36,.30) 18%,
             rgba(225,29,36,.30) 82%,transparent);pointer-events:none;z-index:1}
.card-h{padding:17px 21px;border-bottom:1px solid var(--rule);
  background:linear-gradient(180deg,var(--paper) 0%,var(--surface-2) 100%);
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.card-f{padding:15px 21px;border-top:1px solid var(--rule);
  background:linear-gradient(0deg,var(--paper) 0%,var(--surface-2) 100%);
  display:flex;gap:9px;flex-wrap:wrap}

/* ── figures ───────────────────────────────────────────────────── */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(196px,1fr));gap:15px;margin-bottom:22px}
.stat{position:relative;background:var(--paper);border:1px solid var(--rule);border-radius:14px;
  padding:18px 20px 19px;overflow:hidden;
  box-shadow:0 1px 2px rgba(14,19,28,.04),0 4px 14px rgba(14,19,28,.05)}

/* the rail down the left says which family this number belongs to */
.stat::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:linear-gradient(180deg,var(--tone,var(--red)),transparent 86%)}
/* and a breath of the same colour in the far corner, so the card is not flat */
.stat::after{content:"";position:absolute;right:-34px;top:-34px;width:104px;height:104px;
  border-radius:50%;pointer-events:none;z-index:0;opacity:.5;
  background:radial-gradient(circle,var(--tone-wash,var(--red-wash)) 0%,transparent 70%)}
.stat > *{position:relative;z-index:1}
.stat .lab{color:var(--ink-faint)}
.stat .v{font-family:var(--head);font-size:1.85rem;font-weight:800;letter-spacing:-.04em;
  margin-top:7px;font-variant-numeric:tabular-nums;color:var(--ink)}
.stat .d{font-size:12.5px;color:var(--ink-muted);margin-top:4px}
.stat.t-ok  {--tone:var(--ok);  --tone-wash:var(--ok-wash)}
.stat.t-warn{--tone:var(--warn);--tone-wash:var(--warn-wash)}
.stat.t-src {--tone:var(--src); --tone-wash:var(--src-wash)}
.stat.t-bad {--tone:var(--bad); --tone-wash:var(--bad-wash)}
.stat.t-ok   .v{color:var(--ok)}
.stat.t-warn .v{color:var(--warn)}
.stat.t-src  .v{color:var(--src)}
.stat.t-bad  .v{color:var(--bad)}

/* ── charts ────────────────────────────────────────────────────── */
.chart{padding:20px 21px}
.chart svg{display:block;width:100%;height:auto;overflow:visible}
.chart .ax{font-family:var(--body);font-weight:700;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;fill:var(--ink-faint)}
.chart .vl{font-family:var(--head);font-size:12.5px;font-weight:800;fill:var(--ink)}
.chart .nm{font-family:var(--body);font-size:12.5px;font-weight:600;fill:var(--ink-2)}
.chart .track{fill:var(--surface-2)}
.chart .zero{fill:var(--ink-faint);font-family:var(--body);font-size:12.5px}

.legend{display:flex;gap:16px;flex-wrap:wrap;padding:0 21px 18px;
  font-size:12.5px;color:var(--ink-muted)}
.legend span{display:inline-flex;align-items:center;gap:7px}
.legend i{width:10px;height:10px;border-radius:3px;flex:none}

@media (prefers-reduced-motion:no-preference){
  .card{transition:box-shadow .24s ease,border-color .24s ease,transform .24s cubic-bezier(.22,.8,.3,1)}
  .card:hover{box-shadow:var(--lift);border-color:var(--rule-2)}
  .stat{transition:box-shadow .24s ease,transform .24s cubic-bezier(.22,.8,.3,1),border-color .24s ease}
  .stat:hover{transform:translateY(-3px);box-shadow:var(--lift);border-color:var(--rule-2)}

  /* bars and segments grow from nothing; they are measurements, so they earn it */
  .bar i{transform-origin:left;animation:growX .85s cubic-bezier(.22,.8,.3,1) .45s both}
  .chart .grow{transform-origin:left;animation:growX .95s cubic-bezier(.22,.8,.3,1) both}
  .chart .fade{animation:chipIn .5s cubic-bezier(.2,1.1,.32,1) both}
  .chart .draw{animation:draw 1.1s cubic-bezier(.22,.8,.3,1) .4s both}

  /* the stage pips light one after another, like a thing completing */
  .pips i{animation:pipIn .34s cubic-bezier(.2,1.2,.32,1) both}
  .pips i:nth-child(1){animation-delay:.42s} .pips i:nth-child(2){animation-delay:.50s}
  .pips i:nth-child(3){animation-delay:.58s} .pips i:nth-child(4){animation-delay:.66s}
  .pips i:nth-child(5){animation-delay:.74s}
}
@keyframes pipIn{from{opacity:0;transform:scaleX(.2)}to{opacity:1;transform:none}}
@keyframes draw{from{stroke-dashoffset:var(--len,600)}to{stroke-dashoffset:0}}

/* ══ legibility ════════════════════════════════════════════════════
   The greys were too pale and the weights too light. #8A92A6 on white
   is about 3.4:1, which fails the accessibility floor for body text,
   and 400 at 15px on a screen across a desk is a squint. Secondary
   text should read as secondary because of its weight and size, not
   because you cannot quite see it. */

:root{
  --ink-2:#2E3747;        /* was #3C4556 */
  --ink-muted:#464E66;    /* was #565d7e — now 7.4:1 on white */
  --ink-faint:#646C83;    /* was #8A92A6 — now 5.1:1, still clearly secondary */
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --ink-2:#D6DCE6; --ink-muted:#B4BCCE; --ink-faint:#949CB2;
}}
:root[data-theme="dark"]{--ink-2:#D6DCE6;--ink-muted:#B4BCCE;--ink-faint:#949CB2}

body{font-size:15.5px;font-weight:450;letter-spacing:-.005em}

/* the small print carries weight instead of relying on size alone */
.lab,.side-nav .grp,.proto,.chart .ax{font-weight:700}
.lab,.side-nav .grp,.chart .ax{font-size:10px;letter-spacing:.12em}
.hint,.stat .d,.card-h p,.topbar .sub,.doc .nm small,.empty p{font-weight:500;color:var(--ink-muted)}
.muted{color:var(--ink-muted);font-weight:500}
td,th{font-weight:500}
th{font-weight:700;color:var(--ink-muted)}
td b,td strong{font-weight:700;color:var(--ink)}
label{font-weight:700;color:var(--ink-2)}
.note,.good,.alert,.info{color:var(--ink-2);font-weight:500}
.chip{font-weight:700}
.stat .lab{color:var(--ink-muted)}

.side-nav a{font-weight:650}

/* monospaced references were the worst of it: tiny, pale and tracked out */
/* scoped out of .side: the rail owns its own colours */
.content .lab,.content .ref,.content .mono,.content [style*="var(--mono)"]{color:var(--ink-muted)}
/* a reference is a code: it gets read back over the phone, so the digits
   need to line up and a 0 needs to not look like an O */
td .lab,.side-user .rl{font-family:var(--mono);font-weight:500;letter-spacing:.04em;
  text-transform:none;font-size:11.5px}
.side-user .rl{text-transform:capitalize;font-family:var(--body);font-weight:600;letter-spacing:0}

/* ── chart furniture ───────────────────────────────────────────── */
.chart .zero{font-size:13.5px;color:var(--ink-muted);font-weight:500;margin:0}
.bars-track i.t-red,.funnel-bar i.t-red,.legend i.t-red{background:var(--red)}
.bars-track i.t-ok, .funnel-bar i.t-ok, .legend i.t-ok {background:var(--ok)}
.bars-track i.t-warn,.funnel-bar i.t-warn,.legend i.t-warn{background:var(--warn-fill)}
.bars-track i.t-src, .funnel-bar i.t-src, .legend i.t-src {background:var(--src)}
.bars-track i.t-bad, .funnel-bar i.t-bad, .legend i.t-bad {background:var(--bad)}

.bars{display:flex;flex-direction:column;gap:14px}
.bars-row{display:grid;grid-template-columns:minmax(124px,1.2fr) minmax(80px,3fr) auto auto;
  align-items:center;gap:14px}
.bars-lab{font-size:13.5px;font-weight:600;color:var(--ink-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bars-track{height:10px;border-radius:5px;background:var(--surface-2);overflow:hidden;min-width:60px}
.bars-track i{display:block;height:100%;border-radius:5px}
.bars-val{font-family:var(--head);font-weight:800;font-size:14px;
  font-variant-numeric:tabular-nums;color:var(--ink);text-align:right;min-width:52px}
.bars-note{font-size:12.5px;color:var(--ink-muted);font-weight:500;
  text-align:right;min-width:92px;white-space:nowrap}
@media (max-width:620px){
  .bars-row{grid-template-columns:1fr auto;grid-template-areas:"lab val" "track track" "note note";gap:6px 12px}
  .bars-lab{grid-area:lab}.bars-val{grid-area:val}.bars-track{grid-area:track}
  .bars-note{grid-area:note;text-align:left}
}

.funnel{display:flex;flex-direction:column;gap:11px}
.funnel-row{display:grid;grid-template-columns:minmax(104px,auto) 1fr;align-items:center;gap:14px}
.funnel-lab{font-size:13.5px;font-weight:600;color:var(--ink-2)}
.funnel-bar{display:block}
.funnel-bar i{display:flex;align-items:center;justify-content:flex-end;height:34px;
  border-radius:8px;padding:0 12px;min-width:34px}
.funnel-bar i b{font-family:var(--head);font-weight:800;font-size:14px;color:#fff;
  font-variant-numeric:tabular-nums}
/* nobody in this stage: an outline, not a block */
.funnel-bar i.none{width:58px;background:transparent;border:1px dashed var(--rule-2);
  justify-content:center;animation:none}
.funnel-bar i.none b{color:var(--ink-faint)}

.donut-wrap{position:relative;display:flex;justify-content:center;align-items:center;padding:6px 21px 14px}
/* .chart svg{width:100%} out-specifies a bare .donut, which is how a
   152px ring ended up 600px wide and filling a card on its own. */
.chart svg.donut{width:152px;height:152px;max-width:100%;flex:none}
.donut-mid{position:absolute;inset:0;display:grid;place-content:center;text-align:center;pointer-events:none}
.donut-mid b{display:block;font-family:var(--head);font-weight:800;font-size:1.15rem;
  letter-spacing:-.03em;font-variant-numeric:tabular-nums;color:var(--ink)}
.donut-mid small{display:block;font-size:11px;color:var(--ink-muted);font-weight:700;margin-top:3px;
  letter-spacing:.04em}

@media (prefers-reduced-motion:no-preference){
  .bars-track i,.funnel-bar i{transform-origin:left;
    animation:growX .85s cubic-bezier(.22,.8,.3,1) both}
}
@media (prefers-reduced-motion:reduce){
  .chart .draw{stroke-dashoffset:0!important}
}

/* ══ the white rail ════════════════════════════════════════════════
   The lighter sidebar, kept switchable so it is one line to go back:

       <html data-rail="light">

   Everything here is scoped. Nothing below touches the charcoal default. */

:root[data-rail="light"] .side{
  background:var(--paper);color:var(--ink);border-right:1px solid var(--rule)}

:root[data-rail="light"] .side-brand{border-bottom-color:var(--rule)}
:root[data-rail="light"] .side-brand b{color:var(--ink)}
:root[data-rail="light"] .side-brand b em{color:var(--red)}
:root[data-rail="light"] .side-brand small{color:var(--ink-faint)}
:root[data-rail="light"] .side-brand .lrm{background-image:url(/img/lr-mark.png);filter:none}

:root[data-rail="light"] .side-org{border-bottom-color:var(--rule)}
:root[data-rail="light"] .side-org .lab{color:var(--ink-muted)}
:root[data-rail="light"] .side-org b{color:var(--ink)}

:root[data-rail="light"] .side-nav a{color:var(--ink-muted)}
:root[data-rail="light"] .side-nav a:hover{background:var(--red-wash);color:var(--red-deep)}
:root[data-rail="light"] .side-nav .grp{color:var(--ink-faint)}
:root[data-rail="light"] .side-nav a.on,
:root[data-rail="light"] .side-nav a.on:hover,
:root[data-rail="light"] .side-nav a.on:focus{
  background:var(--red);color:#fff;box-shadow:0 2px 10px rgba(225,29,36,.28)}

:root[data-rail="light"] .side-foot{border-top-color:var(--rule)}
:root[data-rail="light"] .side-foot a,
:root[data-rail="light"] .side-user .rl{color:var(--ink-muted)}
:root[data-rail="light"] .side-user .nm{color:var(--ink)}
:root[data-rail="light"] .side-foot .btn-ghost{color:var(--ink-muted)}
:root[data-rail="light"] .side-foot .btn-ghost:hover{background:var(--surface-2);color:var(--ink)}

/* ══ icons, and the menu under your name ══════════════════════════ */
.usermenu[hidden]{display:none}

.side-nav a{gap:11px}
.ico{flex:none;width:18px;height:18px;opacity:.85}
.side-nav a .ico{opacity:.72;transition:opacity .16s ease,transform .18s cubic-bezier(.22,.8,.3,1)}
.side-nav a:hover .ico{opacity:1}
.side-nav a.on .ico{opacity:1}

/* the person, and everything that belongs to them */
.side-foot{position:relative}
.side-user{display:flex;align-items:center;gap:10px;width:100%;margin:0;padding:8px 9px;
  border:1px solid transparent;border-radius:10px;background:transparent;text-align:left;
  font-family:var(--body);cursor:pointer;color:inherit;
  transition:background .16s ease,border-color .16s ease}

.side-user .who{flex:1;min-width:0}
.side-user .ico{opacity:.62;transition:transform .2s cubic-bezier(.22,.8,.3,1)}
:root[data-rail="light"] .side-user .ico{opacity:.5}
.side-user[aria-expanded="true"] .ico{transform:rotate(180deg)}


.usermenu{position:absolute;left:12px;right:12px;bottom:calc(100% - 6px);z-index:40;
  background:var(--paper);border:1px solid var(--rule);border-radius:12px;padding:6px;
  box-shadow:0 10px 34px rgba(14,19,28,.16),0 2px 8px rgba(14,19,28,.08)}
.usermenu a,.usermenu button{display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 11px;border:0;border-radius:8px;background:transparent;text-decoration:none;
  font-family:var(--body);font-size:13.5px;font-weight:600;color:var(--ink-2);
  cursor:pointer;text-align:left;transition:background .14s ease,color .14s ease}
.usermenu a:hover,.usermenu button:hover{background:var(--red-wash);color:var(--red-deep)}
.usermenu a.on{background:var(--surface-2);color:var(--ink)}
.usermenu form{margin:0}
.usermenu > form::before{content:"";display:block;height:1px;background:var(--rule);margin:6px 4px}

/* On charcoal the menu is a panel floating above a dark rail, so it keeps its
   own light surface rather than dissolving into the sidebar. */
.side-user{color:#E6EAF1}
.side-user:hover,.side-user[aria-expanded="true"]{
  background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.12)}
.usermenu{box-shadow:0 14px 40px rgba(0,0,0,.45)}

:root[data-rail="light"] .side-user{color:inherit}
:root[data-rail="light"] .side-user:hover,
:root[data-rail="light"] .side-user[aria-expanded="true"]{
  background:var(--surface-2);border-color:var(--rule)}
:root[data-rail="light"] .usermenu{
  box-shadow:0 10px 34px rgba(14,19,28,.16),0 2px 8px rgba(14,19,28,.08)}

@media (prefers-reduced-motion:no-preference){
  .side-nav a:hover .ico{transform:translateX(1px)}
  .usermenu{opacity:0;transform:translateY(6px) scale(.985);transform-origin:bottom center;
    transition:opacity .16s ease,transform .2s cubic-bezier(.22,.8,.3,1)}
  .usermenu.in{opacity:1;transform:none}
}

/* ══ the info tip ══════════════════════════════════════════════════
   Background and reasoning belong behind a small amber "i", not spread
   across the page in a blue box. Warnings stay inline — nobody hovers
   an icon to find out something is wrong. */
.infotip{position:relative;display:inline-flex;vertical-align:middle;margin-left:6px}
.infotip-btn{width:17px;height:17px;flex:none;padding:0;border:0;border-radius:50%;
  background:var(--warn-fill);color:#fff;font-family:var(--head);font-weight:800;
  font-size:11px;line-height:17px;text-align:center;cursor:pointer;
  transition:transform .14s cubic-bezier(.22,.8,.3,1),box-shadow .16s ease,background .16s ease}
.infotip-btn:hover,.infotip-btn[aria-expanded="true"]{
  background:#B87A00;box-shadow:0 0 0 3px rgba(210,142,4,.22)}
.infotip-btn:focus-visible{outline:2px solid var(--warn-fill);outline-offset:2px}

.infotip-pop{position:absolute;z-index:60;left:50%;top:calc(100% + 9px);translate:-50% 0;
  width:max-content;max-width:min(320px,72vw);padding:12px 14px;
  background:var(--ink);color:#F2F5F9;border-radius:10px;
  font-family:var(--body);font-size:12.5px;font-weight:500;line-height:1.55;
  text-align:left;white-space:normal;box-shadow:0 10px 30px rgba(14,19,28,.3)}
.infotip-pop[hidden]{display:none}
.infotip-pop b{display:block;font-family:var(--head);font-weight:800;font-size:12.5px;
  letter-spacing:-.01em;color:#fff;margin-bottom:4px}
.infotip-pop::before{content:"";position:absolute;left:50%;top:-5px;translate:-50% 0;
  width:10px;height:10px;rotate:45deg;background:var(--ink);border-radius:2px}
/* near the right edge the balloon would hang off the page */
.infotip.edge .infotip-pop{left:auto;right:0;translate:none}
.infotip.edge .infotip-pop::before{left:auto;right:4px;translate:none}
/* low on the page it opens upward instead */
.infotip.up .infotip-pop{top:auto;bottom:calc(100% + 9px)}
.infotip.up .infotip-pop::before{top:auto;bottom:-5px}

@media (prefers-reduced-motion:no-preference){
  .infotip-btn:hover{transform:scale(1.14)}
  .infotip-pop{animation:tipIn .16s cubic-bezier(.22,.8,.3,1) both}
  .infotip.up .infotip-pop{animation-name:tipInUp}
}
@keyframes tipIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@keyframes tipInUp{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

/* a heading row that carries one */
.card-h h2 .infotip,.card-h h3 .infotip,label .infotip{margin-left:7px}

/* ══ motion that reports state ═════════════════════════════════════
   Entrance animation plays once and is over in under a second, which is
   why the app felt static while you were using it. Everything below
   fires on a CHANGE — a document arriving, a bar moving, a figure going
   up — so the interface keeps answering you after the page has landed. */

/* ── bars ─────────────────────────────────────────────────────────── */
.bar{position:relative;height:7px;background:var(--surface-3);border-radius:4px;
  overflow:hidden;min-width:80px}
.bar i{display:block;height:100%;border-radius:4px;position:relative;
  background:linear-gradient(90deg,var(--ok) 0%,#2FA86A 100%)}
/* a highlight riding the leading edge, so a bar that moves is seen to move */
.bar i::after{content:"";position:absolute;right:0;top:0;bottom:0;width:18px;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55));border-radius:4px}
.bar.full i{background:linear-gradient(90deg,var(--ok) 0%,#34B877 100%)}

@media (prefers-reduced-motion:no-preference){
  /* width is animated, not jumped: when a document lands the bar visibly travels */
  .bar i{transition:width .7s cubic-bezier(.22,.8,.3,1)}
  .bar.busy::before{content:"";position:absolute;inset:0;border-radius:4px;
    background:linear-gradient(100deg,transparent 20%,rgba(225,29,36,.45) 50%,transparent 80%);
    background-size:220% 100%;animation:shimmer .9s linear infinite}
  /* and it pulses once the moment it completes */
  .bar.full i{animation:barDone .7s cubic-bezier(.3,1.4,.4,1) 1}
}
@keyframes barDone{0%{filter:brightness(1)}35%{filter:brightness(1.45)}100%{filter:brightness(1)}}

/* ── a document arriving ──────────────────────────────────────────── */
@media (prefers-reduced-motion:no-preference){
  .doc{transition:background .25s ease}
  .doc .ic{transition:background .3s ease,color .3s ease,transform .3s cubic-bezier(.3,1.4,.4,1)}

  /* the row the file is going into */
  .doc.uploading{background:var(--red-wash)}
  .doc.uploading .ic{animation:pulse 1s ease-in-out infinite}
  .doc.uploading::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
    background:linear-gradient(90deg,transparent,var(--red),transparent);
    background-size:50% 100%;animation:sweep 1.1s linear infinite}
  .doc{position:relative}

  /* the moment it is in: the tick lands and a green wash runs across */
  .doc.landed .ic{animation:tickIn .5s cubic-bezier(.3,1.5,.4,1) 1}
  .doc.landed{animation:greenWash 1.1s ease-out 1}

  /* a document sent back should be impossible to miss */
  .doc.bounced{animation:nudge .42s cubic-bezier(.36,.07,.19,.97) 1}
}
@keyframes pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.1);opacity:.72}}
@keyframes sweep{from{background-position:-60% 0}to{background-position:160% 0}}
@keyframes tickIn{0%{transform:scale(.3) rotate(-25deg);opacity:0}
  60%{transform:scale(1.18) rotate(4deg);opacity:1}100%{transform:none;opacity:1}}
@keyframes greenWash{0%{background:var(--ok-wash)}100%{background:transparent}}
@keyframes nudge{10%,90%{transform:translateX(-2px)}30%,70%{transform:translateX(4px)}
  50%{transform:translateX(-4px)}100%{transform:none}}

/* ── a figure that changed ────────────────────────────────────────── */
@media (prefers-reduced-motion:no-preference){
  .stat .v{transition:color .3s ease}
  .stat.bumped{animation:bump .55s cubic-bezier(.3,1.4,.4,1) 1}
  .stat.bumped .v{animation:flash .9s ease-out 1}
}
@keyframes bump{0%{transform:none}35%{transform:translateY(-5px) scale(1.015)}100%{transform:none}}
@keyframes flash{0%{color:var(--red)}100%{}}

/* ── the region Livewire is rebuilding ────────────────────────────── */
@media (prefers-reduced-motion:no-preference){
  .lr-busy{position:relative}
  .lr-busy::after{content:"";position:absolute;inset:0;z-index:5;pointer-events:none;border-radius:14px;
    background:linear-gradient(100deg,transparent 25%,rgba(225,29,36,.06) 50%,transparent 75%);
    background-size:220% 100%;animation:shimmer 1s linear infinite}
  /* rows re-enter after a filter change, so switching tabs is visibly a change */
  tbody.replay tr{animation:none}
  tbody.replay tr{animation:rowIn .4s cubic-bezier(.22,.8,.3,1) both}
}

/* ── stage pips fill one after another ────────────────────────────── */
.pips i{height:6px;width:26px;border-radius:3px;background:var(--surface-3);transition:background .3s ease}
.pips i.on{background:var(--ok)} .pips i.now{background:var(--red)}
@media (prefers-reduced-motion:no-preference){
  .pips i.now{animation:nowPulse 2.2s ease-in-out infinite}
}
@keyframes nowPulse{0%,100%{box-shadow:0 0 0 0 rgba(225,29,36,.5)}
  60%{box-shadow:0 0 0 5px rgba(225,29,36,0)}}

/* ── buttons say they are working ─────────────────────────────────── */
@media (prefers-reduced-motion:no-preference){
  .btn[wire\:loading]{position:relative}
  .btn:disabled{opacity:.72}
}

/* ══ the assessment ════════════════════════════════════════════════ */
.verdict{border-width:1px}
.verdict.ok{border-color:var(--ok)}
.verdict.held{border-color:var(--warn-fill)}
.verdict::before{background:linear-gradient(90deg,transparent,currentColor 18%,currentColor 82%,transparent);
  opacity:.35}
.verdict.ok::before{color:var(--ok)} .verdict.held::before{color:var(--warn-fill)}
.verdict-mark{width:52px;height:52px;flex:none;border-radius:50%;display:grid;place-items:center;
  font-family:var(--head);font-size:26px;font-weight:800;color:#fff}
.verdict.ok .verdict-mark{background:var(--ok)}
.verdict.held .verdict-mark{background:var(--warn-fill)}

.finding{display:flex;gap:15px;padding:18px 21px;border-bottom:1px solid var(--rule);position:relative}
.finding:last-child{border-bottom:none}
.finding::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px}
.finding.warn::before{background:var(--bad)}
.finding.note::before{background:var(--warn-fill)}
.finding.done::before,.finding.fixed::before{background:var(--ok)}
.finding-mark{width:28px;height:28px;flex:none;border-radius:8px;display:grid;place-items:center;
  font-family:var(--head);font-weight:800;font-size:14px;margin-top:1px}
.finding.warn .finding-mark{background:var(--bad-wash);color:var(--bad)}
.finding.note .finding-mark{background:var(--warn-wash);color:var(--warn)}
.finding.done .finding-mark,.finding.fixed .finding-mark{background:var(--ok-wash);color:var(--ok)}
.finding-body{flex:1;min-width:0}
.finding-body > b{display:block;font-size:14.5px;font-weight:700;color:var(--ink)}
.finding-body > p{font-size:13.5px;color:var(--ink-2);line-height:1.6;margin-top:5px;max-width:78ch}
.finding.fixed{opacity:.72}
.finding-body p.cleared{color:var(--ink-2);font-style:italic}
.finding-body p.who{font-size:12.5px;color:var(--ink-faint);margin-top:4px}

.finding-ev{display:flex;flex-wrap:wrap;gap:7px;margin-top:10px}
.finding-ev span{display:inline-flex;align-items:baseline;gap:6px;background:var(--surface-2);
  border:1px solid var(--rule);border-radius:7px;padding:4px 9px;font-size:12px;
  font-variant-numeric:tabular-nums;color:var(--ink-2)}
.finding-ev i{font-style:normal;font-size:10px;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-faint)}

.finding-clear{margin-top:12px;padding:14px;background:var(--surface-2);
  border:1px solid var(--rule);border-radius:10px;max-width:62ch}
.finding-clear label{font-size:13px}
.finding-clear textarea{font-size:14px;resize:vertical}

/* the chip that says where a deal stands, on the list and the deal itself */
.rev-chip{display:inline-flex;align-items:center;gap:6px}
.rev-chip b{font-variant-numeric:tabular-nums}

@media (prefers-reduced-motion:no-preference){
  .finding{animation:rowIn .4s cubic-bezier(.22,.8,.3,1) both}
  .finding:nth-child(2){animation-delay:.30s} .finding:nth-child(3){animation-delay:.36s}
  .finding:nth-child(4){animation-delay:.42s} .finding:nth-child(n+5){animation-delay:.46s}
  .verdict.held .verdict-mark{animation:nowPulse 2.4s ease-in-out infinite}
  .verdict.ok .verdict-mark{animation:tickIn .55s cubic-bezier(.3,1.5,.4,1) 1}
}
