/* ==========================================================================
   Yantra shell

   The visual idea is a piece of equipment rather than a website. It runs on
   a machine you own and it should read that way: dark ink, warm ivory type,
   brass used structurally for rules, labels and live state rather than as a
   glow. Every tool sits in the same chassis, but each keeps its own material
   inside its panel — the bill parser looks like thermal paper, the chat
   window doesn't. The chassis is the constant; the tools have texture.
   ========================================================================== */

:root{
  /* ── the palette ────────────────────────────────────────────────────
     Light, and built for a working interface rather than a landing page.
     Every value below was measured against WCAG 2.1 on the panel it sits
     on, not chosen by eye: ink 17.9:1, muted 7.6:1, dim 4.8:1, accent
     6.3:1. The first draft had a dim at 3.6 — fine for large text and a
     failure for the small uppercase labels it is actually used on, which
     is the sort of thing that only shows up if you measure it.

     The names are unchanged from the dark theme on purpose. They are used
     in 369 places across nine panels, and renaming them for tidiness would
     be a large diff with no user-visible benefit and a real chance of
     missing one. --brass is now indigo; it was always "the accent".
     ─────────────────────────────────────────────────────────────────── */

  --void:#f4f6fb;            /* the page behind everything */
  --panel:rgba(255,255,255,.78);
  --raised:#ffffff;
  --line:rgba(15,23,42,.10);
  --line-soft:rgba(15,23,42,.06);

  --ivory:#0f172a;           /* primary text — the name is historical */
  --muted:#475569;
  --dim:#5b6b80;

  --brass:#4f46e5;           /* the accent: indigo, from the reference */
  --brass-dim:#a5b4fc;
  --brass-wash:rgba(79,70,229,.07);
  --violet:#7c3aed;
  --cyan:#0891b2;

  --live:#047857;
  --alert:#be123c;

  /* ── the gloss ──────────────────────────────────────────────────────
     Glassmorphism belongs on chrome and not on content. A 20px backdrop
     blur is beautiful behind a hero section and expensive behind a
     scrolling table of four hundred rows, and translucency over a
     gradient costs exactly the text contrast measured above.

     So: the rail, the header and the cards are glass. Tables, figures and
     anything somebody reads for minutes at a time sit on solid white.
     ─────────────────────────────────────────────────────────────────── */
  /* The reference drops to 45% opacity, which is right behind a hero
     headline and wrong behind a 9px label: sampled on screen, that glass
     painted as rgb(201,206,216) and took small text down to 3.0:1. Chrome
     that carries fine print needs to stay near opaque; the gloss reads in
     the gradient, the inner highlight and the shadow, not in how much of
     the page shows through. */
  --gloss: linear-gradient(135deg, rgba(255,255,255,.95), rgba(255,255,255,.86));
  --gloss-edge: 1px solid rgba(255,255,255,.9);
  --gloss-shadow:
    0 18px 38px -16px rgba(15,23,42,.10),
    0 2px 6px -2px rgba(15,23,42,.05),
    inset 0 1px 0 0 rgba(255,255,255,.95);
  --gloss-lift:
    0 26px 50px -14px rgba(79,70,229,.16),
    0 0 0 1px rgba(79,70,229,.10),
    inset 0 1px 0 0 rgba(255,255,255,1);

  --sans:"Plus Jakarta Sans","Archivo",system-ui,-apple-system,sans-serif;

  /* The signature. A gradient-filled headline is the single strongest "this
     is an AI product" signal in the reference, and the first version of this
     theme had none — which is most of why it read as a plain admin panel. */
  --ink-gradient:linear-gradient(135deg,#4f46e5 0%,#7c3aed 48%,#0284c7 100%);
  --accent-gradient:linear-gradient(135deg,#6366f1 0%,#8b5cf6 52%,#4f46e5 100%);
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  --rail:250px;
  --ease:cubic-bezier(.16,1,.3,1);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0;height:100%}
body{
  /* Three very faint colour fields rather than a flat tint. Fixed rather
     than scrolling, so the background stays put while content moves over
     it — a wash that scrolls reads as a texture and distracts. */
  /* Five colour fields, not three. The reference uses indigo, cyan, violet,
     rose and emerald — and the fifth and fourth are what stop it reading as
     "a blue page". Three made something tasteful and inert. */
  background-color:#f7f9fd;
  background-image:
    radial-gradient(at 8% 6%,   rgba(99,102,241,.20) 0px, transparent 52%),
    radial-gradient(at 94% 10%, rgba(6,182,212,.18) 0px, transparent 50%),
    radial-gradient(at 52% 48%, rgba(139,92,246,.13) 0px, transparent 54%),
    radial-gradient(at 84% 88%, rgba(244,63,94,.10) 0px, transparent 50%),
    radial-gradient(at 12% 84%, rgba(16,185,129,.11) 0px, transparent 50%);
  background-attachment:fixed;
  color:var(--ivory);
  font-family:var(--sans);font-size:15px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow:hidden;
}
a{color:inherit}
:focus-visible{outline:2px solid var(--brass);outline-offset:3px;border-radius:2px}
::selection{background:var(--brass-wash);color:var(--ivory)}

/* ---------- chassis ------------------------------------------------- */
.chassis{display:grid;grid-template-columns:var(--rail) 1fr;height:100%}

/* Chrome gets the glass. It is a fixed surface that never scrolls, so the
   backdrop blur is painted once rather than on every frame of a long list. */
.rail{
  background:var(--gloss);
  backdrop-filter:blur(20px) saturate(180%);
  -webkit-backdrop-filter:blur(20px) saturate(180%);
  border-right:var(--gloss-edge);
  box-shadow:1px 0 24px -8px rgba(15,23,42,.07);
  display:flex;flex-direction:column;min-height:0;
}

.brandplate{
  padding:20px 20px 18px;border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:11px;
}
.brandplate .glyph{
  width:26px;height:26px;flex:none;color:var(--brass);
}
.brandplate h1{
  font-family:var(--mono);font-size:14px;font-weight:600;margin:0;
  letter-spacing:.28em;text-transform:uppercase;
}
.brandplate small{
  display:block;font-family:var(--mono);font-size:9px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--dim);margin-top:3px;letter-spacing:.14em;
}

/* ---------- navigation ---------------------------------------------- */
nav{padding:14px 12px;overflow-y:auto;flex:1;min-height:0}
.navlabel{
  font-family:var(--mono);font-size:9px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--dim);padding:8px 8px 10px;
}
.navitem{
  display:flex;align-items:center;gap:11px;width:100%;
  padding:9px 10px;margin-bottom:2px;border:0;border-radius:3px;
  background:none;color:var(--muted);font-family:var(--sans);font-size:14px;
  cursor:pointer;text-align:left;position:relative;
  transition:background .14s var(--ease),color .14s var(--ease);
}
.navitem svg{width:17px;height:17px;flex:none;opacity:.75}
.navitem:hover{background:rgba(255,255,255,.75);color:var(--ivory)}
.navitem[aria-current="page"]{
  background:linear-gradient(135deg,rgba(255,255,255,.95),rgba(238,242,255,.8));
  color:var(--ivory);
  box-shadow:0 4px 12px -6px rgba(79,70,229,.3),inset 0 1px 0 rgba(255,255,255,1);
}
/* The active marker is a brass rule on the leading edge — the one place the
   accent appears in navigation, so it never competes with itself. */
.navitem[aria-current="page"]::before{
  content:"";position:absolute;left:0;top:8px;bottom:8px;width:2px;
  background:var(--brass);border-radius:0 2px 2px 0;
}
.navitem[aria-current="page"] svg{opacity:1;color:var(--brass)}

/* ---------- status rail ---------------------------------------------
   The signature element. A self-hosted box has real state — is the model
   resident, is anything queued, how much disk is left — and on a rented
   server that state is normally invisible until something breaks. Putting
   it permanently in the corner is what makes this feel like equipment
   rather than a tab.
   ------------------------------------------------------------------- */
.status{
  border-top:1px solid var(--line);padding:14px 16px 16px;
  font-family:var(--mono);font-size:10.5px;
}
.status h2{
  font-size:9px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--dim);margin:0 0 11px;font-weight:500;
}
.status.lean h2{font-size:0}
.status.lean h2::before{content:"Status";font-size:9px}
.stat{display:flex;align-items:center;gap:8px;padding:3px 0;color:var(--muted)}
.stat .val{margin-left:auto;color:var(--ivory);font-variant-numeric:tabular-nums}
.lamp{
  width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--dim);box-shadow:0 0 0 2px rgba(255,255,255,.03);
}
.lamp.on{background:var(--live);animation:breathe 3.4s ease-in-out infinite}
.lamp.busy{background:var(--brass);animation:breathe 1s ease-in-out infinite}
.lamp.off{background:var(--alert)}
@keyframes breathe{0%,100%{opacity:.45}50%{opacity:1}}

/* Members get the two lamps that affect them and none of the machine's
   private business. */
.status.lean .owner-only{display:none}


.meter{height:2px;background:var(--line);border-radius:1px;margin-top:9px;overflow:hidden}
.meter i{display:block;height:100%;background:var(--brass-dim)}

/* ---------- viewport -------------------------------------------------- */
.viewport{overflow-y:auto;min-height:0;position:relative}
/* Wide by default.
   1180px was a reading measure, right for prose and wrong for a workspace:
   on a 1440px screen it left 260px of empty gutter either side while the
   dashboard's three columns squeezed into what was left. A page of panels
   and figures wants the screen; only running text needs a limit, and the
   places that carry running text set their own below. */
.inner{max-width:1760px;margin:0 auto;padding:34px 40px 72px}
.inner > .pagehead p,
.inner > .pagehead .lede{max-width:62ch}
@media(max-width:720px){.inner{padding:26px 20px 60px}}

.pagehead{margin-bottom:34px}
/* The eyebrow was mono uppercase in dim grey — a dark-theme idiom that
   reads as drab on a light page. It is a badge now: indigo on an indigo
   wash, the same treatment the reference uses for its AI pills. */
/* Written as `.pagehead .eyebrow, .eyebrow` because `.pagehead p` further
   down is specificity (0,1,1) and quietly beat a bare `.eyebrow` at (0,1,0)
   — the badge got its shape and lost its colour, which looked like the
   colour had been chosen badly rather than never applied. */
.pagehead .eyebrow,
.eyebrow{
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.10em;
  text-transform:uppercase;color:#4338ca;margin:0 0 14px;
  padding:5px 12px;border-radius:999px;
  background:linear-gradient(135deg,rgba(99,102,241,.13),rgba(139,92,246,.13));
  border:1px solid rgba(99,102,241,.24);
}
.eyebrow::before{
  content:"";width:6px;height:6px;border-radius:50%;
  background:var(--accent-gradient);
  box-shadow:0 0 0 3px rgba(99,102,241,.18);
}

/* Extrabold and gradient-filled. Weight 600 in flat slate is what an admin
   panel looks like; 800 with the accent gradient running through it is the
   thing the reference does on every heading, and it is most of the
   difference in presence. */
.pagehead h2{
  font-size:44px;font-weight:800;letter-spacing:-.035em;margin:0;line-height:1.04;
  background:var(--ink-gradient);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  /* A gradient fill cannot be a focus target's visible text, and some
     printers drop it, so the real colour stays underneath. */
  padding-bottom:.06em;
}
@media print{.pagehead h2{-webkit-text-fill-color:#0f172a;color:#0f172a}}
.pagehead p{color:var(--muted);margin:14px 0 0;max-width:58ch;font-size:16px;
  line-height:1.62;font-weight:500}
@media(max-width:720px){.pagehead h2{font-size:31px}}

/* ---------- tool grid --------------------------------------------------
   Cards are instrument plates: a brass hairline along the top edge, a
   monospace index, and an honest list of what the tool consumes. Knowing a
   tool needs the OCR engine and the 7B is useful on a small server.
   --------------------------------------------------------------------- */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:16px}

/* ── the header the home page uses instead of a rail ────────────────── */
.topbar{
  position:sticky;top:0;z-index:40;padding:16px 24px 0;
  grid-column:1 / -1;
}
.topinner{
  max-width:1760px;margin:0 auto;
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:14px 20px;border-radius:18px;
  background:linear-gradient(135deg,rgba(255,255,255,.95),rgba(255,255,255,.86));
  backdrop-filter:blur(20px) saturate(180%);
  -webkit-backdrop-filter:blur(20px) saturate(180%);
  border:1px solid rgba(99,102,241,.14);
  box-shadow:0 18px 38px -22px rgba(30,41,59,.18),inset 0 1px 0 0 #fff;
}
.topbrand{display:flex;align-items:center;gap:14px}
.topbrand .mark{
  width:42px;height:42px;border-radius:13px;flex:none;
  display:flex;align-items:center;justify-content:center;
  background:var(--accent-gradient);color:#fff;
  box-shadow:0 8px 20px -8px rgba(99,102,241,.6);
}
.topbrand .mark svg{width:22px;height:22px}
.topbrand h1{
  font-family:var(--mono);font-size:15px;font-weight:700;margin:0;
  letter-spacing:.24em;text-transform:uppercase;
}
.topbrand small{display:block;color:var(--dim);font-size:11.5px;margin-top:3px}
.topbrand .badge{
  font-family:var(--sans);font-size:9.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:#4338ca;padding:3px 9px;border-radius:999px;
  background:linear-gradient(135deg,rgba(99,102,241,.13),rgba(139,92,246,.13));
  border:1px solid rgba(99,102,241,.24);
}
.topacts{display:flex;align-items:center;gap:10px;flex:none}
.topwho{
  background:none;border:0;padding:0;cursor:pointer;
}
@media(max-width:720px){
  .topbrand small{display:none}
  .topacts .btn.ghost{display:none}
}

/* A tool that brings its own navigation gets the whole window. */
body.tool-fullbleed .rail{display:none}
body.tool-fullbleed .chassis{grid-template-columns:1fr}
body.tool-fullbleed .inner{max-width:none;padding:0}
body.tool-fullbleed .viewport{overflow:hidden}

/* On home the rail is gone and the page is the width of the window. */
body.nohome-rail .rail{display:none}
body.nohome-rail .chassis{grid-template-columns:1fr}
body.nohome-rail .inner{padding-top:26px}

/* ── the launcher ───────────────────────────────────────────────────
   Tiles rather than cards. The difference is that a tile carries a figure
   from its own data — "18 filed, 1 needs a human" — so there is a reason
   to come back to this page. A grid of names and taglines is a menu, and
   nobody revisits a menu. */
.launch{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));
  gap:18px;
}
.tile{
  position:relative;overflow:hidden;cursor:pointer;text-align:left;
  background:var(--gloss);
  backdrop-filter:blur(14px) saturate(160%);
  -webkit-backdrop-filter:blur(14px) saturate(160%);
  border:1px solid rgba(99,102,241,.12);border-radius:20px;
  padding:20px 22px 18px;
  box-shadow:0 20px 44px -24px rgba(30,41,59,.20),
             0 2px 8px -3px rgba(30,41,59,.06),inset 0 1px 0 0 #fff;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),
             border-color .3s var(--ease);
}
.tile:hover{
  transform:translateY(-5px);border-color:rgba(99,102,241,.40);
  box-shadow:0 30px 56px -20px rgba(99,102,241,.28),
             0 0 0 1px rgba(99,102,241,.13),inset 0 1px 0 0 #fff;
}
.tile.off{opacity:.62;cursor:default}
.tile.off:hover{transform:none;box-shadow:0 20px 44px -24px rgba(30,41,59,.20)}
.tilehead{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.tilehead svg{
  width:36px;height:36px;padding:8px;border-radius:11px;color:#4f46e5;
  background:linear-gradient(135deg,rgba(99,102,241,.14),rgba(139,92,246,.14));
  border:1px solid rgba(99,102,241,.18);
  transition:transform .3s var(--ease);
}
.tile:hover .tilehead svg{transform:scale(1.06) rotate(-3deg)}
.tile h3{font-size:17px;font-weight:800;letter-spacing:-.02em;margin:0 0 6px}
.tile > p{margin:0 0 16px;color:var(--muted);font-size:13.5px;line-height:1.55}
.tilestat{
  font-family:var(--mono);font-size:11.5px;color:var(--muted);
  padding-top:13px;border-top:1px solid var(--line-soft);
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;min-height:38px;
}
.tilestat b{font-size:17px;font-weight:700;color:var(--ivory)}
.tilestat .warn{
  color:var(--alert);border:1px solid rgba(190,18,60,.25);border-radius:999px;
  padding:2px 8px;font-size:10px;letter-spacing:.05em;text-transform:uppercase;
}

/* Home sits above the tools and is always there, whatever is turned on. */
.navitem.home{margin-bottom:6px}

.card{
  position:relative;overflow:hidden;
  background:var(--gloss);
  backdrop-filter:blur(14px) saturate(160%);
  -webkit-backdrop-filter:blur(14px) saturate(160%);
  border:1px solid rgba(99,102,241,.12);border-radius:20px;
  padding:24px 24px 21px;text-align:left;cursor:pointer;
  box-shadow:
    0 20px 44px -24px rgba(30,41,59,.20),
    0 2px 8px -3px rgba(30,41,59,.06),
    inset 0 1px 0 0 #fff;
  transition:transform .35s var(--ease), box-shadow .35s var(--ease),
             border-color .35s var(--ease);
}
.card::before{
  content:"";position:absolute;left:-1px;right:-1px;top:-1px;height:1px;
  background:var(--accent-gradient);opacity:0;
  transition:opacity .3s var(--ease);
}
/* The lift from the reference. Cards are chrome — you look at a grid of
   them for a moment and click one — so the glass and the movement belong
   here, unlike a table you read for minutes. */
.card:hover{
  border-color:rgba(99,102,241,.42);
  transform:translateY(-6px) scale(1.012);
  box-shadow:
    0 32px 60px -20px rgba(99,102,241,.30),
    0 0 0 1px rgba(99,102,241,.14),
    inset 0 1px 0 0 #fff;
}
.card:hover::before{opacity:1}

.card .index{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;color:#94a3b8;
  display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;
}
/* The icon sits in a tinted tile rather than floating grey on white. Small
   change, and it is the difference between a list of links and a set of
   product tiles. */
.card .index svg{
  width:34px;height:34px;padding:7px;border-radius:11px;color:#4f46e5;
  background:linear-gradient(135deg,rgba(99,102,241,.14),rgba(139,92,246,.14));
  border:1px solid rgba(99,102,241,.18);
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
.card:hover .index svg{
  transform:scale(1.06) rotate(-3deg);
  box-shadow:0 8px 18px -8px rgba(99,102,241,.5);
}
.card h3{font-size:19px;font-weight:800;margin:0 0 8px;letter-spacing:-.02em}
.card p{color:var(--muted);font-size:13.5px;margin:0;line-height:1.5}
.needs{display:flex;gap:6px;margin-top:16px;flex-wrap:wrap}
/* Pills, not chips. Rounded, tinted, bordered in the accent — the badge
   treatment the reference uses everywhere and the first draft used nowhere,
   which is why everything on the page was the same shade of nothing. */
.need{
  font-family:var(--sans);font-size:10px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:#4338ca;border-radius:999px;padding:4px 10px;
  background:linear-gradient(135deg,rgba(99,102,241,.11),rgba(139,92,246,.11));
  border:1px solid rgba(99,102,241,.22);
}

/* ---------- shared tool furniture -------------------------------------
   Tools use these rather than shipping their own buttons and panels, so a
   new tool looks native on the day it is dropped in.
   -------------------------------------------------------------------- */
/* Content sits on solid white, not glass.
   Translucency over the page wash costs the measured contrast, and a
   backdrop blur behind a scrolling table repaints on every frame. The
   panel gets the gloss *shadow* and edge, which is where the richness
   actually reads, without the cost. */
.panel{
  background:var(--raised);
  border:1px solid rgba(99,102,241,.10);
  border-radius:20px;padding:26px 28px;margin-bottom:20px;
  box-shadow:
    0 24px 48px -22px rgba(30,41,59,.16),
    0 3px 10px -4px rgba(30,41,59,.06),
    inset 0 1px 0 0 #fff;
}
/* Section labels get the accent rather than grey. Every label on the page
   being the same dim slate is what made the first draft read as flat. */
.panel > h3{
  font-family:var(--sans);font-size:11px;font-weight:800;letter-spacing:.13em;
  text-transform:uppercase;color:#4338ca;margin:0 0 18px;
  display:flex;align-items:center;gap:9px;
}
.panel > h3::after{
  content:"";flex:1;height:1px;
  background:linear-gradient(90deg,rgba(99,102,241,.22),transparent);
}
.panel > h3{
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--dim);margin:0 0 16px;font-weight:500;
}

.btn{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;
  background:var(--accent-gradient);
  color:#fff;border:0;border-radius:11px;
  padding:12px 22px;cursor:pointer;font-weight:700;
  box-shadow:0 10px 25px -5px rgba(99,102,241,.45),
             0 2px 6px -2px rgba(79,70,229,.30),
             inset 0 1px 1px 0 rgba(255,255,255,.40);
  transition:transform .18s var(--ease), box-shadow .18s var(--ease),
             filter .18s var(--ease);
}
.btn:hover{
  filter:brightness(1.08) saturate(1.06);
  transform:translateY(-2px);
  box-shadow:0 18px 34px -8px rgba(99,102,241,.55),
             0 0 0 1px rgba(99,102,241,.20),
             inset 0 1px 1px 0 rgba(255,255,255,.5);
}
.btn:active{transform:translateY(0)}
.btn:disabled{
  background:#e2e8f0;color:#94a3b8;cursor:not-allowed;
  box-shadow:none;transform:none;filter:none;
}
.btn.ghost{
  background:linear-gradient(180deg,rgba(255,255,255,.9),rgba(244,246,251,.7));
  color:var(--muted);border:1px solid var(--line);
  box-shadow:0 2px 6px -2px rgba(15,23,42,.06),inset 0 1px 0 rgba(255,255,255,1);
}
.btn.ghost:hover{
  color:var(--brass);border-color:var(--brass-dim);
  box-shadow:0 8px 18px -8px rgba(79,70,229,.28),inset 0 1px 0 rgba(255,255,255,1);
}

.field{
  width:100%;background:#fff;border:1px solid var(--line);border-radius:9px;
  color:var(--ivory);font-family:var(--sans);font-size:14.5px;padding:11px 14px;
  resize:none;
  box-shadow:inset 0 1px 2px rgba(15,23,42,.04);
  transition:border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.field:focus{
  border-color:var(--brass);outline:none;
  box-shadow:0 0 0 3px rgba(79,70,229,.13),inset 0 1px 2px rgba(15,23,42,.03);
}
.field::placeholder{color:var(--dim)}

.hint{font-family:var(--mono);font-size:10.5px;color:var(--dim)}
.hidden{display:none !important}

.notice{
  border-left:2px solid var(--alert);background:rgba(196,85,61,.08);
  padding:13px 16px;border-radius:0 3px 3px 0;font-size:14px;
}
.notice b{
  display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--alert);margin-bottom:5px;font-weight:600;
}

.working{
  display:flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:12px;color:var(--muted);padding:16px 0;
}
.spin{
  width:8px;height:8px;border-radius:50%;background:var(--brass);
  animation:breathe 1.1s ease-in-out infinite;
}

/* ---------- mobile ------------------------------------------------------ */
.railtoggle{display:none}
@media(max-width:860px){
  .chassis{grid-template-columns:1fr}
  .rail{
    position:fixed;inset:0 auto 0 0;width:var(--rail);z-index:40;
    transform:translateX(-100%);transition:transform .22s var(--ease);
  }
  body.rail-open .rail{transform:none}
  body.rail-open::after{
    content:"";position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:30;
  }
  .railtoggle{
    display:flex;align-items:center;gap:10px;position:sticky;top:0;z-index:20;
    background:var(--panel);border-bottom:1px solid var(--line);
    padding:12px 16px;width:100%;border-left:0;border-right:0;border-top:0;
    color:var(--ivory);font-family:var(--mono);font-size:12px;
    letter-spacing:.16em;text-transform:uppercase;cursor:pointer;
  }
  .railtoggle svg{width:18px;height:18px;color:var(--brass)}
}

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

/* ---------- gate ------------------------------------------------------
   Sign-in stands alone: no chassis, no navigation, nothing to interact
   with but the one thing you came to do.
   -------------------------------------------------------------------- */
.gate{
  display:flex;align-items:center;justify-content:center;
  min-height:100vh;padding:28px;
}
.gate-card{width:100%;max-width:376px}
.gate-mark{display:flex;align-items:center;gap:12px;margin-bottom:30px}
.gate-mark svg{width:30px;height:30px;color:var(--brass)}
.gate-mark h1{
  font-family:var(--mono);font-size:15px;font-weight:600;margin:0;
  letter-spacing:.28em;text-transform:uppercase;
}
.gate h2{font-size:25px;font-weight:600;margin:0 0 8px;letter-spacing:-.02em}
.gate .sub{color:var(--muted);margin:0 0 26px;font-size:14.5px;line-height:1.5}
.gate label{
  display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--dim);margin:0 0 6px;
}
.gate .field{margin-bottom:16px}
.gate .btn{width:100%;padding:12px}

/* ---------- account block in the rail ---------------------------------- */
.account{
  border-top:1px solid var(--line);padding:12px;
}
.account button{
  display:flex;align-items:center;gap:10px;width:100%;background:none;border:0;
  color:var(--muted);font-family:var(--sans);font-size:13px;text-align:left;
  padding:8px 10px;border-radius:3px;cursor:pointer;
}
.account button:hover{background:var(--raised);color:var(--ivory)}
.avatar{
  width:24px;height:24px;flex:none;border-radius:50%;
  background:var(--brass-wash);border:1px solid var(--brass-dim);color:var(--brass);
  font-family:var(--mono);font-size:10px;font-weight:600;
  display:flex;align-items:center;justify-content:center;
}
.account .who{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.account .role{font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim)}

/* ---------- catalogue toggles ------------------------------------------ */
.card.off{opacity:.62}
.card .switch{
  position:absolute;right:18px;bottom:18px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
  border:1px solid var(--line);border-radius:2px;padding:3px 9px;
  background:none;color:var(--dim);cursor:pointer;
}
.card .switch.on{border-color:var(--brass-dim);color:var(--brass);background:var(--brass-wash)}
.card .switch:hover{border-color:var(--brass);color:var(--brass)}

/* ---------- admin table ------------------------------------------------- */
.users{width:100%;border-collapse:collapse;font-size:13.5px}
.users th{
  text-align:left;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--dim);font-weight:500;
  padding:0 10px 9px;border-bottom:1px solid var(--line);
}
.users td{padding:11px 10px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
.users .em{font-family:var(--mono);font-size:12px}
.toolset{display:flex;gap:5px;flex-wrap:wrap}
.toolset button{
  font-family:var(--mono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid var(--line);border-radius:2px;padding:2px 7px;
  background:none;color:var(--dim);cursor:pointer;
}
.toolset button.on{border-color:var(--brass-dim);color:var(--brass);background:var(--brass-wash)}
