
:root{
  --void:#0a0d14;--panel:#111726;--panel2:#161d30;--rule:#222b41;--rule2:#2c3854;
  --dim:#8994ab;--mute:#5d6880;--hit:#e3b967;--pos:#6fe0d0;--neg:#ff8a80;
  --display:'Archivo',system-ui,sans-serif;--body:'Instrument Sans',system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --pad:env(safe-area-inset-bottom,0px);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
body{margin:0;background:var(--void);color:#e7ebf3;font-family:var(--body);font-size:16px;line-height:1.55}
h1,h2,h3{font-family:var(--display);font-weight:800;letter-spacing:-.025em;margin:0;line-height:1.1}
h2{font-size:22px}h3{font-size:15px;font-weight:700;letter-spacing:-.01em}
a{color:var(--hit)}
:focus-visible{outline:2px solid var(--hit);outline-offset:2px;border-radius:3px}
.wrap{max-width:1080px;margin:0 auto;padding:0 clamp(14px,3vw,28px)}
.mono{font-family:var(--mono)}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.eyebrow{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:var(--mute)}

/* nav */
.legacy-header{border-bottom:1px solid var(--rule);background:rgba(10,13,20,.92);
  backdrop-filter:blur(12px);position:sticky;top:0;z-index:50}
header .wrap{display:flex;align-items:center;gap:14px;height:58px}
/* The lockup. TenthCard is nine letters; the card after them is the
   tenth character. The name does the counting, so the mark never has to
   explain itself.

   All dimensions are em, so the card is a fixed fraction of the type and
   cannot drift when the size changes. Baseline aligned and deliberately
   taller than the caps — a shape matching cap height would read as a
   letter, and it is not one. */
.brand{font-family:var(--display);font-weight:800;font-size:16px;letter-spacing:-.03em;
  display:inline-flex;align-items:baseline;gap:.15em;line-height:1;
  text-decoration:none;color:inherit}
.brand i{width:.63em;height:.88em;border-radius:.07em;flex:0 0 auto;
  transform-origin:50% 62%;transform:rotate(-8deg) translateY(.07em);
  background:linear-gradient(112deg,#6fe0d0,#7fa4ff 40%,#bf94ff 70%,#ffc98a);
  animation:navRock 7.5s ease-in-out 1.2s infinite}
.tabs{display:flex;gap:4px;margin-left:12px}
.tabs button{min-height:34px;padding:0 13px;border-radius:6px;border:1px solid transparent;
  background:transparent;color:var(--dim);font:600 13.5px var(--body);cursor:pointer}
.tabs button[aria-current="true"]{background:var(--panel2);color:#fff;border-color:var(--rule)}
header .who{margin-left:auto;display:flex;align-items:center;gap:10px;
  font-size:12px;color:var(--mute)}

/* controls */
button.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:42px;padding:0 16px;border-radius:7px;border:1px solid var(--rule);
  background:transparent;color:#e7ebf3;font:600 14px var(--body);cursor:pointer}
button.btn:hover{background:var(--panel2);border-color:var(--rule2)}
button.btn.pri{background:var(--hit);color:#181203;border-color:var(--hit)}
button.btn.pri:hover{background:#f0c878}
button.btn.sm{min-height:34px;padding:0 11px;font-size:13px}
button.btn.danger{color:var(--neg);border-color:#4a2b2b}
button.btn:disabled{opacity:.45;cursor:not-allowed}
input,select{width:100%;min-height:42px;padding:9px 11px;border-radius:7px;
  border:1px solid var(--rule);background:#0d1220;color:#e7ebf3;
  font:400 16px var(--body)}
input:focus,select:focus{outline:2px solid var(--hit);outline-offset:-1px;border-color:transparent}
label.fl{display:block;font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;color:var(--mute);margin:0 0 5px}

/* cards + panels */
.panel{border:1px solid var(--rule);border-radius:11px;background:var(--panel);padding:18px}
.stats{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  border-radius:11px;overflow:hidden;margin:20px 0}
@media(min-width:680px){.stats{grid-template-columns:repeat(4,1fr)}}
.stat{background:var(--panel);padding:16px 18px}
.stat .k{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--mute)}
.stat .v{font-family:var(--display);font-weight:800;font-size:25px;letter-spacing:-.03em;
  margin-top:7px;font-variant-numeric:tabular-nums}
.stat .m{font-size:12px;color:var(--mute);margin-top:3px}
.pos{color:var(--pos)}.neg{color:var(--neg)}

/* table */
.tbl{width:100%;border-collapse:collapse;font-size:14px}
.tbl th{text-align:left;font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;color:var(--mute);
  padding:9px 10px;border-bottom:1px solid var(--rule);white-space:nowrap}
.tbl td{padding:11px 10px;border-bottom:1px solid #1a2133;vertical-align:top}
.tbl tr:hover td{background:var(--panel2)}
.tbl .r{text-align:right}
.tbl .nm{font-weight:600}
.tbl .sub{font-size:11.5px;color:var(--mute);margin-top:2px}
.scroller{overflow-x:auto;-webkit-overflow-scrolling:touch}
.pill{display:inline-block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;padding:2px 7px;border-radius:99px;
  border:1px solid var(--rule);color:var(--mute)}
.pill.exact,.pill.high{color:var(--pos);border-color:rgba(111,224,208,.35)}
.pill.medium{color:var(--hit);border-color:rgba(227,185,103,.4)}
.pill.low,.pill.none{color:var(--neg);border-color:#4a2b2b}

.empty{text-align:center;padding:52px 20px;color:var(--mute)}
.empty h3{color:#e7ebf3;margin-bottom:8px}
.note{font-size:13px;color:var(--dim);line-height:1.5}
.warnbox{border:1px solid rgba(227,185,103,.35);background:rgba(227,185,103,.07);
  border-radius:9px;padding:13px 15px;font-size:13.5px;color:#f0dcae;margin:14px 0}
.grid2{display:grid;gap:12px}
@media(min-width:640px){.grid2{grid-template-columns:1fr 1fr}}
.row-sp{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.spacer{flex:1}
section[hidden]{display:none}
.step{display:flex;gap:8px;margin:0 0 18px;flex-wrap:wrap}
.step span{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  padding:5px 10px;border-radius:99px;border:1px solid var(--rule);color:var(--mute)}
.step span.on{color:#181203;background:var(--hit);border-color:var(--hit);font-weight:600}
.toast{position:fixed;left:50%;bottom:calc(22px + var(--pad));transform:translateX(-50%);
  background:#e7ebf3;color:#0a0d14;font:600 13.5px var(--body);padding:10px 16px;
  /* ABOVE EVERY OVERLAY. This was z-index:99, which sits under the edit
     sheet (150) and the scanner (200) — so an error raised by anything
     you do INSIDE a sheet was painted behind it and never seen. That is
     what made the Trade Desk look like it did nothing when Record it
     failed, and the same toast then flashed for its last second when the
     sheet closed, which read as an error caused by cancelling.
     Every tool in the suite reports failures through this element, so
     the fix belongs here rather than in any one of them. */
  border-radius:99px;z-index:250;opacity:0;pointer-events:none;transition:opacity .18s;
  max-width:90vw;text-align:center}
.toast.on{opacity:1}
.gate{max-width:400px;margin:14vh auto;padding:0 20px}
@media(prefers-reduced-motion:reduce){*{transition:none!important}}

/* ---------- buyout bulk tiers ----------
   Replaces a four-column table in a horizontal scroller. On a phone that
   table squeezed the rate and offer inputs until their own numbers were
   clipped, which is exactly the moment a seller is leaning over to read
   them. This stacks instead: the tier name on its own line, the three
   fields below it, each wide enough for the figure it holds. */
.tiers{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  border-radius:11px;overflow:hidden}
.tier{background:var(--panel);padding:13px 14px}
.tier-nm{font-weight:600;font-size:14px;margin-bottom:9px}
.tier-fields{display:grid;gap:10px;grid-template-columns:repeat(3,minmax(0,1fr))}
.tier-f{display:block;min-width:0}
.tier-f .fl{display:block;font-family:var(--mono);font-size:9.5px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;color:var(--mute);margin:0 0 4px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A currency field that cannot clip its own value: the $ is furniture
   outside the input, and the input keeps a floor width. */
.tier-f .money{position:relative;display:block}
.tier-f .money::before{content:"$";position:absolute;left:9px;top:50%;
  transform:translateY(-50%);color:var(--mute);font:600 13px var(--mono);pointer-events:none}
.tier-f .money input{padding-left:20px}
.tier-f input{width:100%;min-width:0;text-align:right;font-size:15px;
  min-height:40px;padding-right:9px}
.tier-f .btn{width:100%;margin-top:5px;font-size:11.5px;min-height:30px;padding:0 6px}
.tier-f .sub{font-size:11px;color:var(--mute);margin-top:4px;text-align:right;
  min-height:14px}
@media(max-width:430px){
  /* Two up, then the offer full width beneath — the offer is the number
     that gets read aloud, so it gets the room. */
  .tier-fields{grid-template-columns:1fr 1fr}
  .tier-f:nth-child(3){grid-column:1/-1}
  .tier-f .sub{text-align:left}
}

/* ---------- tap to edit ----------
   The affordance IS the feature. Tap-to-edit that looks like plain text
   is a secret, so every editable value carries a dotted underline and
   answers to hover, focus and touch. Nothing here is decoration: strip
   the underline and a dealer never discovers the thing works. */
.te{border-bottom:1px dashed var(--rule2);cursor:pointer;position:relative;
  border-radius:3px;padding:0 2px;margin:0 -2px;transition:background .12s,border-color .12s}
.te:hover,.te:focus-visible{background:#141b2b;border-bottom-color:var(--hit);outline:none}
.te:focus-visible{box-shadow:0 0 0 2px var(--hit)}
.te.editing{border-bottom-color:transparent;background:transparent;padding:0;margin:0}
.te.saving{opacity:.5;pointer-events:none}
.te.te-ok{background:#12301f;border-bottom-color:#3ddc97}
.te.te-bad{border-bottom-color:#ff8a80}
.te-input{font:inherit;color:#e7ebf3;background:#0d1220;border:1px solid var(--hit);
  border-radius:6px;padding:3px 7px;width:100%;min-width:72px;max-width:100%;
  text-align:inherit;font-variant-numeric:tabular-nums}
textarea.te-input{min-height:64px;resize:vertical}
/* The reason a save was refused, next to the value that refused it and
   staying there until the next attempt. */
.te-err{display:block;font:500 11.5px var(--body);color:#ff8a80;
  margin-top:3px;white-space:normal;max-width:22ch}
td .te-err{max-width:16ch}
/* A hint that a whole panel is editable, shown once rather than per row. */
.te-hint{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute)}

/* ---------- suite shell ---------- */
:root{--safe:env(safe-area-inset-bottom,0px);--rail:238px}
/* The sign-in screen wears the wordmark at heading size.

   Only the size is set here; everything that makes it the wordmark —
   the card AFTER the name, the -8deg tilt, the 63:88 proportions, the
   rock — comes from .brand, so the gate and the rail cannot drift apart.
   They had: the gate used to carry a `.fchip`, a 14x19 untilted chip
   sitting BEFORE the name. Wrong side, wrong ratio, no tilt.

   .brand's own font-size would win here on specificity, so 22px is
   restated to keep h2's size. At 22px the card computes to 13.9 x 19.4,
   within half a pixel of the chip it replaces — this change moves and
   tilts the mark, it does not resize it. */
.gate h2.brand{font-size:22px}
.shell{display:grid;grid-template-columns:var(--rail) 1fr;min-height:100vh}
@media(max-width:900px){.shell{grid-template-columns:1fr}}
.rail{border-right:1px solid var(--rule);background:#080b11;padding:16px 12px;
  display:flex;flex-direction:column;gap:3px;position:sticky;top:0;height:100vh;overflow-y:auto}
@media(max-width:900px){
  .rail{position:fixed;inset:0 auto 0 0;width:262px;z-index:80;height:100dvh;
    transform:translateX(-100%);transition:transform .22s ease;box-shadow:0 0 40px rgba(0,0,0,.6)}
  .rail.open{transform:none}
  .scrim{position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:70;display:none}
  .scrim.on{display:block}
}
.scrim{display:none}
.brand{display:inline-flex;align-items:baseline;gap:.15em;line-height:1;
  font-family:var(--display);font-weight:800;font-size:16.5px;letter-spacing:-.03em;
  padding:6px 8px 14px;text-decoration:none;color:inherit}
.brand i{width:.63em;height:.88em;border-radius:.07em;flex:0 0 auto;
  transform-origin:50% 62%;transform:rotate(-8deg) translateY(.07em);
  background:linear-gradient(112deg,#6fe0d0,#7fa4ff 40%,#bf94ff 70%,#ffc98a);
  animation:navRock 7.5s ease-in-out 1.2s infinite}
.rail .grp{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:#3f4a63;padding:14px 9px 6px}
.rail a.nav{display:flex;align-items:center;gap:9px;padding:8px 9px;border-radius:7px;
  text-decoration:none;color:var(--dim);font-size:14px;font-weight:500;min-height:38px}
.rail a.nav:hover{background:#0f1523;color:#e7ebf3}
.rail a.nav[aria-current="page"]{background:var(--panel2);color:#fff;font-weight:600}
.rail a.nav .n{font-family:var(--mono);font-size:9.5px;color:#3f4a63;width:16px;flex:0 0 auto}
.rail a.nav[aria-current="page"] .n{color:var(--hit)}
.rail a.nav.soon{opacity:.45}
.rail a.nav.soon::after{content:"soon";margin-left:auto;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.1em;text-transform:uppercase;color:#3f4a63}
.rail .foot{margin-top:auto;padding:14px 9px 0;border-top:1px solid var(--rule);
  font-size:12px;color:var(--mute)}
.topbar{display:none}
@media(max-width:900px){
  .topbar{display:flex;align-items:center;gap:12px;height:54px;padding:0 14px;
    border-bottom:1px solid var(--rule);position:sticky;top:0;z-index:60;
    background:rgba(10,13,20,.94);backdrop-filter:blur(12px)}
}
.burger{width:40px;height:40px;border-radius:8px;border:1px solid var(--rule);
  background:transparent;color:#e7ebf3;font-size:17px;cursor:pointer}
main{padding:22px clamp(14px,3vw,30px) calc(60px + var(--safe));max-width:1120px;width:100%}
.grid3{display:grid;gap:12px}
@media(min-width:760px){.grid3{grid-template-columns:repeat(3,1fr)}}
.field{margin-bottom:12px}
.seg{display:flex;gap:6px;flex-wrap:wrap}
.seg button{min-height:38px;padding:0 13px;border-radius:7px;border:1px solid var(--rule);
  background:transparent;color:var(--dim);font:500 13px var(--mono);cursor:pointer}
.seg button[aria-pressed="true"]{background:var(--hit);color:#181203;border-color:var(--hit);
  font-weight:600}
.panel.flush{padding:0;overflow:hidden}
.tbl tr.pick{cursor:pointer}
.pill.ok{color:var(--pos);border-color:rgba(111,224,208,.35)}
.pill.warn{color:var(--hit);border-color:rgba(227,185,103,.4)}
.pill.bad{color:var(--neg);border-color:#4a2b2b}
.toast[data-kind="bad"]{background:#ff8a80;color:#2a0f0c}
.r{text-align:right}
.eyebrow{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:var(--mute)}
textarea{width:100%;min-height:76px;padding:9px 11px;border-radius:7px;border:1px solid var(--rule);
  background:#0d1220;color:#e7ebf3;font:400 16px var(--body);resize:vertical}

/* customer-facing scan-to-pay panel — read across a table, in bad light */
.paypanel{margin:14px 0 0;padding:20px;border:1px solid var(--rule);border-radius:11px;
  background:#0d1220;text-align:center}
.paypanel .amt{font-family:var(--display);font-weight:800;font-size:38px;letter-spacing:-.035em;
  line-height:1}
.paypanel .qr{margin:16px auto 10px;width:208px;height:208px;background:#fff;border-radius:9px;
  padding:0;display:flex;align-items:center;justify-content:center}
.paypanel .qr svg{border-radius:9px;display:block}
.paypanel .hand{font-size:13px;color:var(--dim);letter-spacing:.06em}

/* scanner viewport — guide corners rather than auto edge detection, so
   a bad frame is visible to the user instead of silently mis-read */
.scanwrap{position:relative;border-radius:12px;overflow:hidden;background:#05070c;
  border:1px solid var(--rule);aspect-ratio:4/3;max-width:640px}
.scanwrap video{width:100%;height:100%;object-fit:cover;display:block}
.guide{position:absolute;inset:0;pointer-events:none;display:flex;
  align-items:center;justify-content:center}
.guide::before{content:"";aspect-ratio:5/7;height:82%;border:2px dashed rgba(227,185,103,.55);
  border-radius:8px}
.guide .corner{position:absolute;width:22px;height:22px;border:3px solid var(--hit)}
.guide .tl{top:9%;left:calc(50% - 29.2%*0.714 - 11px);border-right:0;border-bottom:0;border-radius:6px 0 0 0}
.guide .tr{top:9%;right:calc(50% - 29.2%*0.714 - 11px);border-left:0;border-bottom:0;border-radius:0 6px 0 0}
.guide .bl{bottom:9%;left:calc(50% - 29.2%*0.714 - 11px);border-right:0;border-top:0;border-radius:0 0 0 6px}
.guide .br{bottom:9%;right:calc(50% - 29.2%*0.714 - 11px);border-left:0;border-top:0;border-radius:0 0 6px 0}
.scanhint{position:absolute;left:0;right:0;bottom:10px;text-align:center;
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:#e7ebf3;text-shadow:0 1px 6px rgba(0,0,0,.9)}

/* The hidden attribute only gets display:none from the UA stylesheet, so
   any display rule of ours beats it — .shell{display:grid} was keeping the
   whole app rendered behind the sign-in panel. Make hidden mean hidden. */
[hidden]{display:none !important}

/* ============================================================
   Full-screen scanner.
   The viewfinder gets the whole display: a bigger frame means the card
   fills more of it, which is what both OCR and the fingerprint need.
   Controls sit in the thumb zone; results arrive as a sheet over a live
   camera rather than replacing it, so the next card can go straight in.
   ============================================================ */
.sf{position:fixed;inset:0;z-index:200;background:#000;display:none;
  flex-direction:column;overflow:hidden}
.sf.open{display:flex}
.sf video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

.sf-guide{position:absolute;inset:0;pointer-events:none;
  display:flex;align-items:center;justify-content:center}
.sf-frame{position:relative;aspect-ratio:5/7;height:58%;max-width:86vw;
  border-radius:14px;box-shadow:0 0 0 100vmax rgba(0,0,0,.45)}
.sf-frame span{position:absolute;width:30px;height:30px;border:3px solid #fff;opacity:.95}
.sf-frame .tl{top:-1px;left:-1px;border-right:0;border-bottom:0;border-radius:12px 0 0 0}
.sf-frame .tr{top:-1px;right:-1px;border-left:0;border-bottom:0;border-radius:0 12px 0 0}
.sf-frame .bl{bottom:-1px;left:-1px;border-right:0;border-top:0;border-radius:0 0 0 12px}
.sf-frame .br{bottom:-1px;right:-1px;border-left:0;border-top:0;border-radius:0 0 12px 0}
.sf.busy .sf-frame span{border-color:var(--hit)}

.sf-top{position:absolute;top:0;left:0;right:0;z-index:3;
  padding:calc(env(safe-area-inset-top,0px) + 10px) 14px 10px;
  display:flex;align-items:center;gap:10px;
  background:linear-gradient(180deg,rgba(0,0,0,.62),transparent)}
.sf-icon{width:44px;height:44px;flex:0 0 auto;border-radius:50%;border:0;
  background:rgba(255,255,255,.16);color:#fff;font-size:19px;cursor:pointer;
  display:flex;align-items:center;justify-content:center;backdrop-filter:blur(6px)}
.sf-icon[aria-pressed="true"]{background:var(--hit);color:#181203}
.sf-count{margin-left:auto;font:600 12px var(--mono);color:#fff;
  background:rgba(0,0,0,.45);padding:7px 12px;border-radius:99px;letter-spacing:.06em}

.sf-hint{position:absolute;left:0;right:0;z-index:3;text-align:center;
  bottom:calc(env(safe-area-inset-bottom,0px) + 150px);
  font:600 13px var(--body);color:#fff;letter-spacing:.02em;
  text-shadow:0 1px 8px rgba(0,0,0,.95);padding:0 24px}

.sf-bar{position:absolute;left:0;right:0;bottom:0;z-index:3;
  padding:18px 20px calc(env(safe-area-inset-bottom,0px) + 22px);
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  background:linear-gradient(0deg,rgba(0,0,0,.72),transparent)}
.sf-shutter{width:76px;height:76px;border-radius:50%;border:5px solid rgba(255,255,255,.9);
  background:#fff;cursor:pointer;flex:0 0 auto;margin:0 auto;
  transition:transform .1s ease}
.sf-shutter:active{transform:scale(.93)}
.sf-shutter:disabled{opacity:.45}
.sf-side{width:56px;flex:0 0 auto;color:#fff;font:600 11px var(--mono);
  letter-spacing:.08em;text-align:center;background:none;border:0;cursor:pointer;
  text-transform:uppercase;opacity:.9;padding:8px 0}
.sf-side[aria-pressed="true"]{color:var(--hit)}

/* results sheet — over the camera, never replacing it */
.sf-sheet{position:absolute;left:0;right:0;bottom:0;z-index:6;max-height:78%;
  background:var(--panel);border-radius:16px 16px 0 0;border-top:1px solid var(--rule);
  transform:translateY(102%);transition:transform .24s cubic-bezier(.2,.9,.3,1);
  display:flex;flex-direction:column;
  padding-bottom:calc(env(safe-area-inset-bottom,0px) + 8px)}
.sf-sheet.up{transform:none}
.sf-grab{width:38px;height:4px;border-radius:2px;background:var(--rule2);
  margin:9px auto 4px;flex:0 0 auto}
.sf-sheet .body{overflow-y:auto;-webkit-overflow-scrolling:touch;padding:6px 16px 14px}
.sf-hit{display:flex;gap:12px;align-items:center;padding:12px 0;
  border-bottom:1px solid #1a2133}
.sf-hit:last-child{border-bottom:0}
.sf-hit img{width:52px;border-radius:4px;flex:0 0 auto;background:#0d1220}
.sf-hit .who{flex:1;min-width:0}
.sf-hit .who .nm{font-weight:650;font-size:15px}
.sf-hit .who .sub{font-size:12px;color:var(--mute);margin-top:2px}
.sf-qty{display:flex;align-items:center;gap:10px;margin:12px 0}
.sf-qty button{width:44px;height:44px;border-radius:10px;border:1px solid var(--rule);
  background:#0d1220;color:#e7ebf3;font-size:20px;cursor:pointer}
.sf-qty .n{font:700 20px var(--mono);min-width:38px;text-align:center}
.sf-sheet select{min-height:44px}
@media(prefers-reduced-motion:reduce){.sf-sheet{transition:none}}

/* ============================================================
   Portfolio grid. Cards are visual objects — a dealer recognises
   artwork faster than a row of text, and the images are already
   in the catalog. List view stays for anyone working the numbers.
   ============================================================ */
.viewtoggle{display:flex;gap:4px;background:#0d1220;border:1px solid var(--rule);
  border-radius:8px;padding:3px}
.viewtoggle button{min-height:34px;padding:0 12px;border:0;border-radius:6px;
  background:transparent;color:var(--dim);font:600 12px var(--mono);cursor:pointer}
.viewtoggle button[aria-pressed="true"]{background:var(--panel2);color:#fff}

.pgrid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.pcard{background:var(--panel);border:1px solid var(--rule);border-radius:12px;
  overflow:hidden;cursor:pointer;display:flex;flex-direction:column;
  transition:border-color .15s ease,transform .1s ease}
.pcard:hover{border-color:var(--rule2)}
.pcard:active{transform:scale(.985)}
.pcard .art{aspect-ratio:5/7;background:#0b0f19;position:relative;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.pcard .art img{width:100%;height:100%;object-fit:contain;display:block}
.pcard .art .noart{font:600 10px var(--mono);color:#33405e;letter-spacing:.12em;
  text-transform:uppercase;padding:0 10px;text-align:center}
.pcard .art .qty{position:absolute;top:7px;right:7px;background:rgba(0,0,0,.72);
  color:#fff;font:700 11px var(--mono);padding:3px 7px;border-radius:99px}
.pcard .meta{padding:10px 11px 12px;display:flex;flex-direction:column;gap:2px;flex:1}
.pcard .nm{font-weight:650;font-size:13.5px;line-height:1.25;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pcard .sub{font-size:11px;color:var(--mute);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pcard .figs{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;margin-top:7px}
.pcard .val{font:700 15px var(--mono);font-variant-numeric:tabular-nums}
.pcard .chg{font:600 11px var(--mono)}
.pcard .approx{font-size:9.5px;color:var(--mute);letter-spacing:.08em;text-transform:uppercase}

/* card detail */
.cdet-hero{background:radial-gradient(120% 80% at 50% 0%,rgba(127,164,255,.14),transparent 70%);
  padding:22px 0 18px;text-align:center;border-bottom:1px solid var(--rule);margin-bottom:18px}
.cdet-hero img{width:min(210px,52vw);border-radius:9px;
  box-shadow:0 18px 44px rgba(0,0,0,.55);display:block;margin:0 auto}
.printings{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  border-radius:10px;overflow:hidden}
.printings .row{background:var(--panel);padding:13px 15px;display:flex;
  align-items:center;justify-content:space-between;gap:12px}
.printings .row.mine{background:var(--panel2);border-left:3px solid var(--hit)}
.printings .lbl{font-size:14px;font-weight:600}
.printings .tag{font:600 9.5px var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--hit);margin-left:8px}
.spark{width:100%;height:70px;display:block}

/* edit sheet */
.editwrap{position:fixed;inset:0;z-index:150;background:rgba(6,9,15,.72);
  display:none;align-items:flex-end;justify-content:center;
  /* A drag on the backdrop must dismiss or do nothing, never scroll the
     page underneath. Without this the sheet and the page fight each
     other and the sheet is close to unusable one-handed. */
  overscroll-behavior:contain;touch-action:none}
.editwrap.open{display:flex}
.editcard{width:100%;max-width:560px;max-height:90dvh;overflow-y:auto;
  background:var(--panel);border:1px solid var(--rule);border-radius:16px 16px 0 0;
  padding:8px 16px calc(env(safe-area-inset-bottom,0px) + 18px);
  /* The card itself scrolls, but its scroll stops at its own ends rather
     than chaining into whatever is behind it. */
  overscroll-behavior:contain;touch-action:pan-y;
  -webkit-overflow-scrolling:touch}
.editcard .scroller{overscroll-behavior:contain}
/* Belt and braces: freeze the page while a sheet is open. :has means no
   module has to remember to add and remove a class, which is the sort of
   bookkeeping that gets forgotten in one place out of twelve. */
html:has(.editwrap.open),
body:has(.editwrap.open){overflow:hidden}
@media(min-width:600px){
  .editwrap{align-items:center}
  .editcard{border-radius:16px;max-height:86dvh}
}
.editcard .grab{width:38px;height:4px;border-radius:2px;background:var(--rule2);
  margin:8px auto 14px}
/* graded ladder */
.ladder{display:grid;gap:1px;background:var(--rule);border:1px solid var(--rule);
  border-radius:10px;overflow:hidden;grid-template-columns:repeat(auto-fit,minmax(84px,1fr))}
.ladder .cell{background:var(--panel);padding:11px 8px;text-align:center}
.ladder .cell.mine{background:var(--panel2);box-shadow:inset 0 -3px 0 var(--hit)}
.ladder .g{font:700 15px var(--mono)}
.ladder .p{font:600 13px var(--mono);margin-top:4px}
.ladder .n{font-size:10px;color:var(--mute);margin-top:2px}
.ladder .cell.thin .p{color:var(--nice,#e3b967)}
.ladder .cell.unreliable .p{color:var(--mute)}
.bandtabs{display:flex;gap:5px;overflow-x:auto;padding-bottom:4px;margin:12px 0 8px}
.bandtabs button{flex:0 0 auto;min-height:34px;padding:0 12px;border-radius:99px;
  border:1px solid var(--rule);background:transparent;color:var(--dim);
  font:600 12px var(--mono);cursor:pointer}
.bandtabs button[aria-pressed="true"]{background:var(--hit);color:#181203;border-color:var(--hit)}

/* ============================================================
   Buyout Desk. The running offer follows you down the page —
   at a table you are looking at the seller, not at the screen,
   and the number they asked for has to be readable in a glance.
   ============================================================ */
.offerbar{position:sticky;bottom:0;z-index:20;display:flex;align-items:center;gap:14px;
  margin:18px -4px 0;padding:12px 16px calc(12px + var(--safe));
  border:1px solid var(--rule);border-radius:12px;background:rgba(17,23,38,.96);
  backdrop-filter:blur(12px);box-shadow:0 -8px 26px rgba(0,0,0,.45)}
.offerbar .k{font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--mute)}
.offerbar .v{font-family:var(--display);font-weight:800;font-size:27px;letter-spacing:-.035em;
  line-height:1.05;font-variant-numeric:tabular-nums}
.offerbar .note{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.offerbar .btn{flex:0 0 auto}
@media(max-width:420px){
  .offerbar{gap:10px;padding-left:13px;padding-right:13px}
  .offerbar .v{font-size:23px}
  .offerbar .note{display:none}
}

/* A row the dealer should look at twice — used for stock that has been
   asleep over a year. Tinted, not shouted. */
.tbl tr.warnrow td{background:rgba(227,185,103,.055)}
.tbl tr.warnrow td:first-child{box-shadow:inset 2px 0 0 rgba(227,185,103,.5)}

/* ============================================================
   Icons and empty-state illustrations.

   Everything is currentColor, so one sprite serves the muted
   sidebar, the amber active state and a coral warning without a
   second copy of the file.
   ============================================================ */
.ic{width:20px;height:20px;flex:0 0 auto;fill:none;stroke:currentColor;
  stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}

/* Beside a screen title. Quiet rather than amber: the accent is
   already carrying the active nav item and every link, and a third
   job would dilute it. */
h2 .ic.screen{width:21px;height:21px;color:var(--dim);
  vertical-align:-2px;margin-right:9px}

.es{width:104px;height:104px;display:block;margin:0 auto 16px;
  fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round;color:var(--rule2)}

@media(max-width:420px){
  .es{width:84px;height:84px;margin-bottom:12px}
}

/* The mark's idle sway. Two degrees over seven and a half seconds — slow
   enough that nobody catches it moving, present enough that the thing
   feels alive. Declared once and shared by both .brand rules. */
@keyframes navRock{
  0%,100%{transform:rotate(-8deg) translateY(.07em)}
  50%    {transform:rotate(-6deg) translateY(.07em)}
}
@media (prefers-reduced-motion:reduce){
  .brand i{animation:none}
}
