/*
 * Jug Scope — Shop Portal styles (WS-J-U3).
 *
 * Jony §4.2: this file is a SIBLING of admin-console/styles.css — same token
 * NAMES, same 4/8/12/16/24/32 spacing, same 8/12/16/999 radii, same 1180px
 * content width, same table-kills-JSON primitive. It is never an import of
 * that file and this unit never touches admin-console/.
 *
 * THE THREE DELIBERATE DIVERGENCES FROM THE OPERATOR CONSOLE (§4.2):
 *   1. Light AND dark, not dark-only. Same token names in both, dark declared
 *      first as the default. The portal is opened in a bright office and in a
 *      hangar; the console is opened by one operator.
 *   2. No operator chrome. No env badge, no lock pill, no TOTP, no standing
 *      danger-zone card. Destructive acts get proportional inline friction on
 *      their own row (WS-J-U4's), not a red gradient zone.
 *   3. A money panel that cannot be clicked (§7.9) — .panel-static below has
 *      no hover state, no cursor change and no click target.
 *
 * CONTRAST: every foreground/background pair used for text is >= 4.5:1 in BOTH
 * themes, measured from rendered styles rather than assumed from the palette.
 * See docs/plans/PORTAL-WAVE2-SHELL.md for the measured table.
 */

/* ── Dark: the default declaration (Jony §4.2 divergence 1) ───────────────── */
:root{
  --bg:#0d0f13;
  --bg-side:#0a0c10;
  --bg-elev:#161a21;
  --bg-elev2:#1d222c;
  --bg-hover:#20262f;
  --border:#282e39;
  --border-soft:#20242d;

  --text:#e7eaf0;
  --text-2:#aab2c0;
  --muted:#8b93a2;

  --accent:#4f8cff;
  --accent-hover:#6ba0ff;
  --accent-dim:#16233d;
  /* Text ON the accent fill. MEASURED, not assumed: white on #4f8cff is
     3.22:1 — it failed the 4.5 floor on the primary button, which is the one
     control every session starts with. Dark ink on the same fill measures
     5.88:1. This is exactly the "verified against the actual token pairs, not
     assumed from the palette" clause in §7.11, and the palette lost. */
  --on-accent:#06121f;
  --safe:#33c076;   --safe-dim:#10301f;
  --warn:#e6a93c;   --warn-dim:#2e2410;
  --danger:#f0575c; --danger-dim:#2c1417;
  --info:#4f8cff;   --info-dim:#16233d;

  --focus:#8ab4ff;

  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  --r-s:8px; --r-m:12px; --r-l:16px; --r-pill:999px;
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-6:24px; --sp-8:32px;
  --content:1180px;
  --shadow:0 1px 0 rgba(255,255,255,.02) inset, 0 8px 24px -12px rgba(0,0,0,.6);
  color-scheme: dark light;
}

/* ── Light: same token names, no new roles ───────────────────────────────── */
@media (prefers-color-scheme: light){
  :root{
    --bg:#f4f6f9;
    --bg-side:#e9edf3;
    --bg-elev:#ffffff;
    --bg-elev2:#f0f3f8;
    --bg-hover:#e2e7ef;
    --border:#c9d0da;
    --border-soft:#dde2ea;

    --text:#14171c;
    --text-2:#3d4450;
    --muted:#59616e;

    --accent:#1857c4;
    --accent-hover:#12459c;
    --accent-dim:#e4ecfb;
    --on-accent:#ffffff;   /* measured 6.55:1 on #1857c4 */
    --safe:#12653c;   --safe-dim:#e2f3ea;
    --warn:#7a4d00;   --warn-dim:#faf0dc;
    --danger:#a3231c; --danger-dim:#fbe6e5;
    --info:#1857c4;   --info-dim:#e4ecfb;

    --focus:#12459c;

    --shadow:0 1px 2px rgba(16,24,40,.06), 0 8px 24px -14px rgba(16,24,40,.35);
    color-scheme: light dark;
  }
}

*{box-sizing:border-box;}
html,body{margin:0;padding:0;min-height:100%;}
body{
  background:var(--bg); color:var(--text);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Inter,sans-serif;
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
  /* §7.11: the page body never scrolls horizontally. Tables scroll inside
     their own .tbl-wrap container instead. */
  overflow-x:hidden;
}
button,input,select,textarea{font-family:inherit; font-size:inherit;}
.mono{font-family:var(--mono);}
.muted{color:var(--muted);}
.sec2{color:var(--text-2);}
.hidden{display:none !important;}
.nowrap{white-space:nowrap;}

/* §7.11: a VISIBLE focus ring on every interactive element, in visual order.
   Never `outline: none`. :focus-visible plus a fallback for older engines. */
a:focus-visible,
button:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible{
  outline:3px solid var(--focus);
  outline-offset:2px;
  border-radius:var(--r-s);
}

a{color:var(--accent);}
a:hover{color:var(--accent-hover);}

/* Skip link — keyboard order starts here, not in the middle of the nav. */
.skip{
  position:absolute; left:var(--sp-2); top:-64px; z-index:50;
  background:var(--bg-elev); color:var(--text); border:1px solid var(--border);
  border-radius:var(--r-s); padding:var(--sp-2) var(--sp-3);
  transition:top .12s ease;
}
.skip:focus{top:var(--sp-2);}

/* ============ APP SHELL ============ */
.app{display:grid; grid-template-columns:248px 1fr; min-height:100vh;}
/* W0b — signed in, holding no memberships. There are no sections to navigate,
   so the sidebar is not rendered AND its column is not reserved. Hiding the
   aside without collapsing the column leaves the page's only content squeezed
   into whatever is left, which is how an honest empty state reads as a broken
   one. */
.app.no-side{grid-template-columns:1fr;}

.side{
  background:var(--bg-side);
  border-right:1px solid var(--border-soft);
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh; overflow-y:auto;
}
.brand{padding:var(--sp-6) var(--sp-4) var(--sp-3);}
.brand-name{font-weight:700; font-size:17px; letter-spacing:-.01em; margin:0;}
.brand-sub{font-size:12px; color:var(--muted); margin:var(--sp-1) 0 0;}
/* Shop switcher: a <select>, not a mode toggle (§7.3) — it changes WHICH
   shop's data is on screen and nothing about who the user is. */
.brand-switch{margin-top:var(--sp-3);}
.brand-switch label{display:block; font-size:12px; color:var(--muted); margin-bottom:var(--sp-1);}
select.shop-switcher{
  width:100%; padding:var(--sp-2) var(--sp-3);
  background:var(--bg-elev2); color:var(--text);
  border:1px solid var(--border); border-radius:var(--r-s);
}

.nav{display:flex; flex-direction:column; gap:2px; padding:var(--sp-2) var(--sp-2) var(--sp-6);}
.nav-item{
  display:block; width:100%; text-align:left;
  padding:var(--sp-2) var(--sp-3);
  background:transparent; color:var(--text-2);
  border:1px solid transparent; border-radius:var(--r-s);
  cursor:pointer;
}
.nav-item:hover{background:var(--bg-hover); color:var(--text);}
.nav-item[aria-current="page"]{
  background:var(--accent-dim); color:var(--text);
  border-color:var(--border); font-weight:600;
}

.main{display:flex; flex-direction:column; min-width:0;}
.topbar{
  display:flex; align-items:center; gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--border-soft);
  background:var(--bg);
  position:sticky; top:0; z-index:10;
}
.hamb{
  display:none;
  background:var(--bg-elev); color:var(--text);
  border:1px solid var(--border); border-radius:var(--r-s);
  padding:var(--sp-2) var(--sp-3); cursor:pointer;
}
.crumb{font-weight:600;}
.topbar-right{margin-left:auto; display:flex; align-items:center; gap:var(--sp-3);}
.who{font-size:13px; color:var(--muted);}

.view{
  width:100%; max-width:var(--content);
  margin:0 auto; padding:var(--sp-6) var(--sp-4) var(--sp-8);
  min-width:0;
}

/* ============ PRIMITIVES ============ */
h1{font-size:24px; letter-spacing:-.015em; margin:0 0 var(--sp-2);}
h2{font-size:18px; letter-spacing:-.01em; margin:0 0 var(--sp-2);}
h3{font-size:15px; margin:0 0 var(--sp-2);}
p{margin:0 0 var(--sp-3);}

.card{
  background:var(--bg-elev); border:1px solid var(--border);
  border-radius:var(--r-m); padding:var(--sp-4);
  box-shadow:var(--shadow);
}
.card + .card{margin-top:var(--sp-4);}

/* §7.9 / §4.2 divergence 3 — a panel that CANNOT be clicked. No hover state,
   no cursor change, no click target. Stated here as a class so the property is
   inspectable rather than a promise in prose. */
.panel-static{cursor:default;}
.panel-static *{cursor:default;}

.btn{
  display:inline-block;
  padding:var(--sp-2) var(--sp-4); min-height:40px;
  background:var(--bg-elev2); color:var(--text);
  border:1px solid var(--border); border-radius:var(--r-s);
  cursor:pointer;
}
.btn:hover{background:var(--bg-hover);}
.btn[disabled]{opacity:.55; cursor:default;}
.btn-primary{background:var(--accent); border-color:var(--accent); color:var(--on-accent);}
.btn-primary:hover{background:var(--accent-hover); border-color:var(--accent-hover);}
.btn-primary[disabled]{background:var(--accent); border-color:var(--accent);}

.tiles{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-4);}
.tile{
  background:var(--bg-elev); border:1px solid var(--border);
  border-radius:var(--r-m); padding:var(--sp-4);
}
.tile-label{font-size:13px; color:var(--muted); margin:0 0 var(--sp-1);}
/* §7.11: no monetary or count value truncates at any width. */
.tile-value{font-size:28px; font-weight:650; letter-spacing:-.02em;
  overflow-wrap:normal; white-space:nowrap; text-overflow:clip;}
.tile-note{font-size:13px; color:var(--text-2); margin:var(--sp-2) 0 0;}

/* Table primitive — sticky uppercase headers, hairline dividers,
   right-aligned monospace for dates (§7.4). */
.tbl-wrap{overflow-x:auto;}
table.tbl{width:100%; border-collapse:collapse; font-size:14px;}
table.tbl th{
  position:sticky; top:0;
  text-align:left; text-transform:uppercase; letter-spacing:.06em;
  font-size:11px; color:var(--muted);
  background:var(--bg-elev);
  padding:var(--sp-2) var(--sp-3);
  border-bottom:1px solid var(--border);
}
table.tbl td{
  padding:var(--sp-3); border-bottom:1px solid var(--border-soft);
  vertical-align:top;
}
table.tbl td.num, table.tbl th.num{text-align:right; font-family:var(--mono);}

/* States. ERROR carries the API code AND human help text, never a bare number
   (§7.3). PARTIAL renders an em dash for the tile that failed. */
.state{border-radius:var(--r-m); padding:var(--sp-4); border:1px solid var(--border);}
.state.err{background:var(--danger-dim); border-color:var(--danger); color:var(--text);}
.state.warn{background:var(--warn-dim); border-color:var(--warn); color:var(--text);}
.state.info{background:var(--info-dim); border-color:var(--info); color:var(--text);}
.state h2{margin-top:0;}
.err-code{font-family:var(--mono); font-size:12px; color:var(--text-2);}

.skel{
  background:var(--bg-elev2); border-radius:var(--r-s);
  height:1em; width:60%;
}

/* The shared aria-live region. It sits OUTSIDE #portal-view (which the router
   clears on every navigation) so it is never removed and re-inserted. */
.live{
  width:100%; max-width:var(--content);
  margin:var(--sp-4) auto calc(-1 * var(--sp-3));
  padding:0 var(--sp-4);
  color:var(--text-2);
}
.live:empty{display:none;}

.hint{color:var(--text-2); font-size:14px;}
.small{font-size:13px;}

/* Sign-in surfaces (W0 on login.html, and the shell's signed-out gate). */
.wrap{
  max-width:520px; margin:0 auto;
  padding:var(--sp-8) var(--sp-4);
}
.card-auth{text-align:left;}
.card-auth h1{margin-bottom:var(--sp-3);}

/* ============ BREAKPOINTS (§7.11) ============ */

/* 880px — the sidebar collapses behind the hamburger (admin-console
   behaviour, inherited). */
@media (max-width:880px){
  .app{grid-template-columns:1fr;}
  .side{
    position:fixed; inset:0 auto 0 0; width:264px; z-index:30;
    transform:translateX(-100%); transition:transform .18s ease;
    border-right:1px solid var(--border);
  }
  .side.open{transform:translateX(0);}
  .hamb{display:inline-block;}
}

/* 560px — tables become STACKED CARDS, one card per row, with the column
   headers as labels. A shop owner opens this on a phone from an email, and a
   horizontally scrolling table on a phone is a table nobody reads. */
@media (max-width:560px){
  .tiles{grid-template-columns:1fr;}
  .view{padding:var(--sp-4) var(--sp-3) var(--sp-8);}
  table.tbl thead{
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
  }
  table.tbl, table.tbl tbody, table.tbl tr, table.tbl td{display:block; width:100%;}
  table.tbl tr{
    background:var(--bg-elev); border:1px solid var(--border);
    border-radius:var(--r-m); padding:var(--sp-2); margin-bottom:var(--sp-3);
  }
  table.tbl td{
    border-bottom:1px solid var(--border-soft);
    display:flex; gap:var(--sp-3); justify-content:space-between;
  }
  table.tbl tr td:last-child{border-bottom:none;}
  table.tbl td::before{
    content:attr(data-label);
    font-size:11px; text-transform:uppercase; letter-spacing:.06em;
    color:var(--muted); flex:0 0 auto;
  }
  table.tbl td.num{text-align:left;}
}

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