/* ==========================================================================
   THEEB design system
   --------------------------------------------------------------------------
   Tokens and shared components for every authenticated surface. Values here
   are the design handoff's, not approximations: the gold ramp, the cream
   surfaces, the 72px header, the 280px sidebar and the table metrics all come
   straight from the prototype's spec.

   Load order: theeb.css first, then the page stylesheet (admin_panel.css,
   customer.css, landing.css), which may only add or override — never redefine
   a token.
   ========================================================================== */

:root{
  /* Typography scale, from the prototype's :root. Body-range sizes collapse
     toward 15px while headings keep their scale, so --fs-16 really is 17px and
     --fs-14 really is 15px — the names are the prototype's, not a mistake. */
  --fs-32:32px; --fs-28:28px; --fs-22:22px; --fs-19:19px; --fs-17:17px;
  --fs-16:17px; --fs-15:16px; --fs-14:15px;
  --fw-r:400; --fw-m:500;

  /* Ink / text */
  --ink:#1E2D3D;
  --ink-800:#15202C;
  --ink-900:#0F1923;
  --slate:#2A3A4A;
  --bl:#3A4A5A;
  --bl-m:#5A6A7A;      /* muted body text */
  --bl-l:#EEF0F3;      /* hairline divider inside cards */

  /* Brand gold */
  --orange:#AD652C;
  --orange-deep:#8E5222;
  --orange-lt:#C2814A;
  --orange-glow-hi:#D49A5E;
  --orange-soft:#F6EEDD;
  --orange-glow:rgba(173,101,44,.12);

  /* Neutrals & surfaces */
  --w:#fff;
  --t:#1E2D3D;
  --g:#5A6A7A;
  --gl:#9BA5AF;
  --gp:#D0D5DA;
  --gb:#F0EEEA;        /* hover / inset tray */
  --bd:#E4E2DC;        /* card + control border */
  --bg:#FCFBF8;
  --warm-bg:#FCFBF8;   /* page background behind cards */
  --muted-ink:#8A8578; /* table headers, meta lines */

  /* Status */
  --gr:#5AA57C;  --gr-soft:rgba(90,165,124,.12);  --gr-txt:#3B6D11;
  --rd:#F87171;  --rd-soft:rgba(248,113,113,.1);  --rd-txt:#B4362F;
  --am:#FBBF24;  --am-soft:rgba(251,191,36,.15);  --am-txt:#B7791F;
  --warn-txt:#C4520A;

  --font-sans:'Albert Sans','Segoe UI',system-ui,-apple-system,sans-serif;

  /* Radii */
  --r-card:14px;
  --r-ctl:9px;
  --r-modal:18px;
  --r-pill:99px;
}

*{margin:0;padding:0;box-sizing:border-box;font-family:var(--font-sans);font-feature-settings:"tnum" 1}
*{scrollbar-width:thin}
*::-webkit-scrollbar{width:6px;height:6px}
*::-webkit-scrollbar-track{background:transparent}
*::-webkit-scrollbar-thumb{background:var(--gp);border-radius:3px}
*::-webkit-scrollbar-thumb:hover{background:var(--gl)}

/* NOTHING MAY SCROLL THE PAGE SIDEWAYS. One overflowing child anywhere makes
   the whole document draggable under a thumb, and on a phone that reads as the
   layout coming loose rather than as a scrollbar.
   `clip`, NOT `hidden`: `hidden` makes the root a scroll container, which
   re-anchors every `position:sticky` descendant to it — the workspace crumb bar
   and the landing masthead both stop sticking. `clip` clips without creating
   one. It is also the honest failure: a browser too old for `clip` ignores the
   line and scrolls as it does today, rather than silently unsticking headers.
   THIS IS THE NET, NOT THE FIX. It hides an overflow instead of removing it, so
   a rule that overflows on purpose still has to be found — see the crumb bar in
   `customer.css`. Vertical scrolling is untouched. */
html{overflow-x:clip}
body{font-size:16px;color:var(--t);background:var(--w)}
/* A media element wider than its column is the other half of the same bug, and
   nothing in this sheet clamped one. NOT `svg`: every svg here is an icon with
   its own width, often inside a flex row narrower than itself, and clamping
   those shrinks icons rather than preventing an overflow. */
img,video,canvas{max-width:100%}
[x-cloak]{display:none!important}
a{color:inherit;text-decoration:none}
button{font-family:inherit}

/* ==========================================================================
   App shell — sidebar + main column, both locked to the viewport so only the
   content area scrolls.
   ========================================================================== */
.app-shell{display:flex;height:100vh;overflow:hidden;position:relative}

.side{width:280px;background:var(--w);border-right:1px solid var(--bd);display:flex;
      flex-direction:column;flex-shrink:0;height:100vh;color:var(--ink)}
/* The sidebar brand. Column rather than row since the lockup carries its own
   wordmark now — the tagline sits under it instead of beside the mark.
   SIZED TO THE BOX IT SITS IN, which is 238px wide (280 less the padding) and
   72px tall. The lockup is 5.4:1, so height is a deceptive dial: 36px is 193px
   across, filling four fifths of the width, and 36 + gap + tagline is 49px of
   the 72. Anything much smaller leaves the header looking empty around it,
   which is what 22px did. The tagline is tracked in rather than the logo held
   back, so the two still read as a heading and its line. */
.logo{padding:0 20px 0 22px;height:72px;display:flex;flex-direction:column;
      align-items:flex-start;justify-content:center;gap:5px;
      border-bottom:1px solid var(--bd);cursor:pointer}
.logo .brand-logo{height:36px;width:auto;display:block}
.logo svg.mark{flex-shrink:0;width:38px;height:38px;filter:drop-shadow(0 2px 8px rgba(173,101,44,.32))}
.logo-text{display:flex;flex-direction:column;justify-content:center;min-width:0}
.logo-name{font-size:17px;font-weight:800;letter-spacing:1.4px;color:var(--ink);line-height:1}
.logo-name span{color:var(--orange)}
.logo-tag{font-size:8px;font-weight:700;letter-spacing:1.15px;color:var(--gp);
          text-transform:uppercase;margin-top:5px;white-space:nowrap}

.nav{flex:1;padding:20px 14px 14px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.nav-section-l{font-size:15px;font-weight:700;color:var(--orange);letter-spacing:-.1px;
               text-transform:uppercase;padding:8px 14px;margin-top:18px;line-height:1.3}
.nav-section-l:first-child{margin-top:0}
.ni{display:flex;align-items:center;gap:12px;padding:8px 14px;cursor:pointer;border-radius:10px;
    font-size:15px;color:var(--bl-m);font-weight:600;transition:all .15s;letter-spacing:-.1px}
.ni:hover{background:var(--gb);color:var(--ink)}
.ni.on{background:var(--orange-soft);color:var(--orange);font-weight:500;
       box-shadow:inset 0 0 0 1px rgba(173,101,44,.28)}
.ni svg{width:19px;height:19px;flex-shrink:0;fill:none;stroke-width:1.7;stroke-linecap:round;
        stroke-linejoin:round;stroke:var(--bl-m);transition:stroke .15s}
.ni svg .accent{stroke:var(--orange);stroke-width:2}
.ni:hover svg{stroke:var(--ink)}
.ni.on svg{stroke:var(--orange)}


/* Sidebar footer: brand tile + the plan/credits card. */
.sbot{margin-top:auto;padding:14px;border-top:1.5px solid var(--bd);
      background:linear-gradient(180deg,var(--w) 0%,var(--warm-bg) 100%)}
.theeb{border-radius:13px;padding:14px 15px;display:flex;align-items:center;gap:12px;
       background:linear-gradient(135deg,#0F1923 0%,#152230 100%);position:relative;overflow:hidden;
       border:1px solid rgba(173,101,44,.32);box-shadow:0 4px 14px rgba(15,25,35,.18)}
.theeb::before{content:'';position:absolute;top:-60px;right:-60px;width:140px;height:140px;
       border-radius:50%;background:radial-gradient(circle,rgba(173,101,44,.32) 0%,transparent 60%);
       pointer-events:none;animation:breathe 4s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:1;transform:scale(1.08)}}
.theeb-av{width:42px;height:42px;flex-shrink:0;z-index:1;display:flex;align-items:center;
       justify-content:center;background:rgba(173,101,44,.15);border-radius:10px;
       border:1px solid rgba(173,101,44,.3)}
.theeb-av svg{width:30px;height:30px}
.theeb-body{position:relative;z-index:1;flex:1;min-width:0}
.theeb-t{font-size:14.5px;font-weight:800;color:#fff;letter-spacing:.1px;line-height:1.2}
.theeb-d{font-size:12px;color:rgba(255,255,255,.78);font-weight:500;margin-top:4px;
       display:flex;align-items:center;gap:5px;line-height:1.3}
.theeb-d::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--orange);
       box-shadow:0 0 0 2px rgba(173,101,44,.32);animation:pulse-dot 2s infinite}
@keyframes pulse-dot{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.7;transform:scale(1.15)}}

.sub-card{margin-top:12px;border-radius:var(--r-card);border:1.5px solid var(--bd);
       padding:15px 16px 14px;background:var(--w);box-shadow:0 2px 8px rgba(15,25,35,.04)}
.sub-card-h{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:11px;gap:10px}
.sub-pkg{display:flex;align-items:center;gap:9px;flex:1;min-width:0}
.sub-pkg-ic{width:34px;height:34px;border-radius:9px;background:var(--orange-soft);color:var(--orange);
       display:flex;align-items:center;justify-content:center;flex-shrink:0;
       border:1px solid rgba(173,101,44,.32)}
/* Column, not inline flow: both children are spans, so without this they run
   onto one line and the tier's margin-top does nothing. It read acceptably
   while the tier was the word "Plan"; a date is long enough to wrap mid-value. */
.sub-pkg-body{flex:1;min-width:0;display:flex;flex-direction:column}
.sub-pkg-name{font-size:14px;font-weight:700;color:var(--ink);line-height:1.2}
.sub-pkg-tier{font-size:10px;color:var(--orange);font-weight:700;letter-spacing:1.2px;
       text-transform:uppercase;margin-top:3px;white-space:nowrap}
.sub-upgrade-btn{margin-left:auto;flex-shrink:0;font-size:12px;font-weight:700;letter-spacing:.3px;
       color:#fff;background:linear-gradient(135deg,var(--orange),var(--orange-deep));border:none;
       border-radius:8px;padding:6px 13px;cursor:pointer;transition:filter .15s}
.sub-upgrade-btn:hover{filter:brightness(1.08)}
.sub-credits-row{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:7px;font-size:11.5px}
.sub-credits-l{color:var(--bl-m);font-weight:600;letter-spacing:.2px}
.sub-credits-l b{color:var(--ink);font-weight:700;font-size:15px;font-variant-numeric:tabular-nums;margin-right:2px}
.sub-credits-r{font-size:11.5px;font-weight:600;color:var(--orange)}
.plt{height:5px;background:var(--bd);border-radius:3px;overflow:hidden}
.plf{height:100%;background:linear-gradient(90deg,var(--orange),var(--orange-glow-hi));
     border-radius:3px;box-shadow:0 0 8px rgba(173,101,44,.4)}
.sub-foot{margin-top:8px;font-size:10px;color:var(--gp);font-weight:600;letter-spacing:.3px;text-align:right}

/* Main column */
.main{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--warm-bg);
      height:100vh;overflow:hidden}
.tophd{height:72px;border-bottom:1px solid var(--bd);background:var(--w);display:flex;
      align-items:center;padding:0 28px;gap:24px;flex-shrink:0}
.tophd-title{font-size:20px;font-weight:800;color:var(--ink);letter-spacing:-.4px}

/* Header search. Grows into the space between the burger and the user pill
   rather than taking a fixed width, and stops at 560px so it does not become a
   letterbox on a wide monitor. */
.search{flex:1;max-width:560px;min-width:0;display:flex;align-items:center;gap:9px;
        height:40px;padding:0 10px 0 13px;background:var(--warm-bg);
        border:0;border-radius:11px;color:var(--gp);
        transition:box-shadow .15s,background .15s}
/* THE FOCUS RING IS A SHADOW BECAUSE THERE IS NO BORDER LEFT TO COLOUR. This
   state used to be `border-color:var(--orange)` plus a soft glow; with the
   border gone the glow was all that remained — 12% orange, which is not a focus
   indicator, and this is a text field a keyboard reaches with ⌘K. The solid 1px
   ring is the border's job moved onto the one property that can do it without
   taking layout back: box-shadow does not affect the box, so the field neither
   shifts nor resizes when it takes focus. */
.search:focus-within{background:var(--w);
        box-shadow:0 0 0 1px var(--orange),0 0 0 4px rgba(173,101,44,.12)}
.search>svg{flex-shrink:0}
.search input{flex:1;min-width:0;border:0;background:none;outline:none;
        font-family:inherit;font-size:13.5px;color:var(--ink)}
.search input::placeholder{color:var(--gp)}
/* `border:0` AND `background:none`, because neither was ever declared and a
   <button> does not start from nothing: what showed around this icon was
   Chrome's own button chrome — a 1px `buttonborder` rule and a `buttonface`
   grey fill — not a rule in this file. Both go together; removing the border
   and leaving the grey face would just trade one piece of UA styling for
   another. The reset `*` at the top of this file covers margin and padding but
   deliberately not border, so controls have to say so themselves. */
.search-mic{flex-shrink:0;width:26px;height:26px;display:flex;align-items:center;
        justify-content:center;border:0;background:none;border-radius:7px;color:var(--gp);
        transition:background .15s,color .15s}
/* :not(:disabled), so the hover fill does not offer a response the button will
   not give. A control that lights up under the cursor and then does nothing is
   the failure this state exists to avoid. */
.search-mic:hover:not(:disabled){background:rgba(173,101,44,.1);color:var(--orange)}
.search-mic:disabled{cursor:default;color:var(--gp)}
/* While the browser is listening, so nobody wonders whether it heard them. */
.search-mic.listening{background:var(--orange);color:#fff}
.search .kbd{flex-shrink:0;font-size:10.5px;font-weight:700;letter-spacing:.4px;
        color:var(--gp);background:var(--w);border:1px solid var(--bd);
        border-radius:6px;padding:3px 6px;line-height:1}
.tophd-r{margin-left:auto;display:flex;align-items:center;gap:8px}
/* `overflow-x:clip` is NOT redundant beside `overflow-y:auto`. A box with one
   axis set to anything but `visible` computes the other from `visible` to
   `auto`, so `overflow-y:auto` alone silently made this a HORIZONTAL scroller
   too — and since `.app-shell` is `overflow:hidden`, the document could not
   move but this could, which is the sideways drag inside the workspace. `clip`
   again rather than `hidden`, to keep `.page-crumb-bar` sticky. */
.content{flex:1;overflow-y:auto;overflow-x:clip;background:var(--warm-bg);padding:0 28px 28px}
.page-body{padding-top:28px}

/* User pill + dropdown */
.user-pill{display:flex;align-items:center;gap:10px;padding:6px 14px 6px 6px;border-radius:8px;
      cursor:pointer;transition:background .15s;position:relative}
.user-pill:hover,.user-pill.open{background:var(--gb)}
.user-pill.open .user-chev{transform:rotate(180deg)}
.user-av{width:36px;height:36px;border-radius:50%;background:var(--ink);color:var(--w);font-size:13px;
      font-weight:800;display:flex;align-items:center;justify-content:center;letter-spacing:.5px;flex-shrink:0}
.user-name{display:flex;flex-direction:column;line-height:1.25;min-width:110px}
.user-name span:first-child{font-size:13.5px;font-weight:700;color:var(--ink);letter-spacing:-.1px}
.user-name span:last-child{font-size:12px;color:var(--bl-m);margin-top:2px;font-weight:500;
      letter-spacing:-.05px}
.user-chev{stroke:var(--gp);flex-shrink:0;transition:transform .2s}
.user-menu{position:absolute;top:calc(100% + 10px);right:0;width:280px;background:var(--w);
      border:1px solid var(--bd);border-radius:var(--r-card);
      box-shadow:0 16px 48px rgba(15,25,35,.16),0 0 0 1px rgba(15,25,35,.03);
      padding:8px;z-index:9998;display:none;
      flex-direction:column;gap:1px;animation:fadeUp .18s ease;cursor:default}
.user-pill.open .user-menu{display:flex}
@keyframes fadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.user-menu-h{display:flex;align-items:center;gap:12px;padding:13px 12px 14px;cursor:default}
.user-menu-av{width:42px;height:42px;border-radius:50%;background:var(--ink);color:var(--w);
      font-size:14px;font-weight:800;display:flex;align-items:center;justify-content:center;
      letter-spacing:.5px;flex-shrink:0}
.user-menu-info{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
.user-menu-name{font-size:15px;font-weight:800;color:var(--ink);letter-spacing:-.2px;line-height:1.3}
.user-menu-email{font-size:12.5px;font-weight:500;color:#888780;letter-spacing:-.05px;
      line-height:1.3;margin-top:1px}
.user-menu-plan{display:inline-flex;align-items:center;gap:5px;font-size:9.5px;font-weight:800;
      letter-spacing:1px;text-transform:uppercase;color:var(--orange);background:var(--orange-soft);
      border:1px solid rgba(173,101,44,.32);border-radius:var(--r-pill);padding:2px 8px;
      line-height:1.3;align-self:flex-start;margin-top:1px}
.user-menu-divider{height:1px;background:var(--bd);margin:5px 6px}
.user-menu-item{display:flex;align-items:center;gap:12px;padding:10px 12px;font-size:14px;
      font-weight:600;color:var(--ink);letter-spacing:-.1px;background:transparent;border:none;
      cursor:pointer;border-radius:9px;text-align:left;line-height:1.35;
      transition:background .12s;width:100%}
.user-menu-item svg{stroke:var(--bl-m);flex-shrink:0}
.user-menu-item:hover{background:var(--gb)}
.user-menu-item:hover svg{stroke:var(--orange)}
.user-menu-item.danger{color:#C63A3A}
.user-menu-item.danger svg{stroke:#C63A3A}
.user-menu-item.danger:hover{background:var(--rd-soft)}

/* ==========================================================================
   Page headers & stat band
   ========================================================================== */
.page-h-t{font-size:32px;font-weight:800;color:var(--ink);letter-spacing:-.6px;line-height:1.15;margin-bottom:8px}
.page-h-t span{color:var(--orange)}
.page-h-d{font-size:15px;font-weight:500;color:var(--bl-m);line-height:1.55;max-width:680px}
.apr-page-h{display:flex;justify-content:space-between;align-items:flex-end;margin-bottom:22px;gap:24px}
.apr-page-sub{font-size:14px;color:var(--muted-ink);margin-top:4px}
.apr-page-sub b{color:var(--orange);font-weight:600}

.apr-preds{display:grid;grid-template-columns:repeat(4,1fr);background:var(--w);
      border:1px solid var(--bd);border-radius:12px;padding:22px 26px;margin-bottom:22px}
.apr-pred{display:flex;flex-direction:column;padding:0 24px;border-left:1px solid #EFE8DC}
.apr-pred:first-child{padding-left:0;border-left:none}
.apr-pred-l{font-size:11px;font-weight:600;letter-spacing:1.4px;text-transform:uppercase;
      color:var(--muted-ink);margin-bottom:6px}
.apr-pred-v{font-size:24px;font-weight:500;color:var(--ink-900);letter-spacing:-.5px;line-height:1.1;
      font-variant-numeric:tabular-nums}
.apr-pred-v.warn{color:var(--warn-txt)}
.apr-pred-v.g{color:var(--gr-txt)}
.apr-pred-sub{font-size:12px;color:var(--muted-ink);margin-top:3px}

/* ==========================================================================
   Buttons & controls
   ========================================================================== */
.btn-primary{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:800;
      color:var(--w);background:var(--orange);border:none;border-radius:var(--r-ctl);padding:11px 18px;
      cursor:pointer;letter-spacing:.2px;transition:all .15s;box-shadow:0 4px 14px rgba(173,101,44,.28)}
.btn-primary:hover:not(:disabled){background:var(--orange-deep);box-shadow:0 6px 18px rgba(173,101,44,.4)}
.btn-primary:disabled{opacity:.55;cursor:default;box-shadow:none}
.btn-primary.danger{background:var(--rd-txt)}
.btn-primary.danger:hover:not(:disabled){background:#8f2a25;box-shadow:0 6px 18px rgba(180,54,47,.35)}
.btn-secondary{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:700;
      color:var(--ink);background:var(--w);border:1.5px solid var(--bd);border-radius:var(--r-ctl);
      padding:10px 16px;cursor:pointer;transition:all .15s}
.btn-secondary:hover:not(:disabled){border-color:var(--ink);background:var(--gb)}
.btn-secondary:disabled{opacity:.55;cursor:default}
.btn-xs{font-size:12.5px;font-weight:700;padding:7px 14px;border-radius:8px;cursor:pointer;
      border:1.5px solid var(--bd);background:var(--w);color:var(--ink);transition:all .15s}
.btn-xs:hover{border-color:var(--ink)}
.icon-btn{width:34px;height:34px;border-radius:9px;border:1.5px solid var(--bd);background:var(--w);
      display:inline-flex;align-items:center;justify-content:center;cursor:pointer;color:var(--bl-m);
      transition:all .15s}
.icon-btn:hover{border-color:var(--orange);color:var(--orange)}
.link-btn{background:none;border:none;color:var(--orange);font-weight:700;font-size:13px;cursor:pointer;padding:0}
.link-btn:hover{text-decoration:underline}

/* Toolbar: search left, filters/actions right */
.jr-toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:16px}
.jr-toolbar-actions{display:flex;gap:10px;align-items:center}
.jr-search{display:flex;align-items:center;gap:9px;flex:0 0 340px;height:42px;border:1.5px solid var(--bd);
      border-radius:10px;padding:0 14px;background:var(--w);color:var(--gl)}
.jr-search input{flex:1;border:none;outline:none;background:none;font-size:14px;color:var(--ink)}
.filter-btn{display:inline-flex;align-items:center;gap:8px;font-size:14px;font-weight:700;color:var(--ink);
      background:var(--w);border:1.5px solid var(--bd);border-radius:10px;height:42px;padding:0 16px;
      cursor:pointer;transition:all .15s}
.filter-btn:hover{border-color:var(--ink)}
.filter-btn .fcount{background:var(--orange);color:#fff;font-size:11px;font-weight:700;min-width:18px;
      height:18px;border-radius:var(--r-pill);display:inline-flex;align-items:center;justify-content:center;padding:0 5px}

/* Sub-tabs (Subscription Plans / Customer Subscriptions) */
.subtabs{display:flex;gap:6px;margin-bottom:24px;border-bottom:1px solid var(--bd)}
.subtab{font-size:15px;font-weight:600;color:var(--bl-m);background:none;border:none;
      border-bottom:2px solid transparent;padding:10px 4px;margin-right:20px;cursor:pointer;transition:color .15s}
.subtab:hover{color:var(--ink)}
.subtab.on{color:var(--orange);border-bottom-color:var(--orange);font-weight:700}

/* ==========================================================================
   Tables
   ========================================================================== */
.dsection{background:var(--w);border:1px solid var(--bd);border-radius:var(--r-card);
      overflow-x:auto;margin-bottom:22px}
.dsection-h{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px;
      border-bottom:1px solid var(--bd)}
.dsection-t{font-size:16px;font-weight:700;color:var(--ink)}
/* The table keeps its 720px floor — the columns genuinely do not fit below it
   and squeezing them produces a wrapped, unreadable grid. What changes is who
   scrolls: .dtable-wrap scrolls sideways so the page itself does not, which is
   the difference between "this table is wide" and "the whole site is broken".
   -webkit-overflow-scrolling keeps it momentum-scrolling on iOS. */
.dtable-wrap{width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.dtable{width:100%;border-collapse:collapse;min-width:720px}
.dtable th{text-align:left;font-size:11px;font-weight:700;letter-spacing:1.2px;text-transform:uppercase;
      color:var(--muted-ink);padding:12px 20px;border-bottom:1px solid var(--bd);background:var(--warm-bg)}
.dtable td{padding:14px 20px;border-bottom:1px solid var(--bl-l);font-size:14px;color:var(--ink);
      vertical-align:middle}
.dtable tr:last-child td{border-bottom:none}
.dtable tbody tr:hover td{background:var(--warm-bg)}
.dtable .num{text-align:right;font-variant-numeric:tabular-nums}
.dtable .right{text-align:right}
.dt-id{display:flex;align-items:center;gap:12px}
.dt-name{font-weight:700;color:var(--ink)}
.dt-sub{font-size:12px;color:var(--bl-m);margin-top:2px}
.av-sq{width:38px;height:38px;border-radius:10px;display:flex;align-items:center;justify-content:center;
      font-weight:800;font-size:13px;color:#fff;flex-shrink:0;background:var(--ink)}
.tbl-empty{padding:36px;text-align:center;color:var(--muted-ink);font-size:14px}

.pill{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:700;padding:4px 10px;
      border-radius:var(--r-pill);letter-spacing:.2px}
.pill.ind{background:#EEF3F7;color:#3A5A72}
.pill.co{background:var(--orange-soft);color:var(--orange)}
.pill.ok{background:var(--gr-soft);color:var(--gr-txt)}
.pill.warn{background:var(--am-soft);color:var(--am-txt)}
.pill.bad{background:var(--rd-soft);color:var(--rd-txt)}
.pill.mut{background:var(--gb);color:var(--bl-m)}
.chip{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink);
      background:var(--warm-bg);border:1px solid var(--bd);padding:4px 11px;border-radius:var(--r-pill)}
.ubar{height:7px;background:var(--bl-l);border-radius:4px;overflow:hidden;width:130px;display:inline-block}
.ubar>i{display:block;height:100%;background:linear-gradient(90deg,var(--orange),var(--orange-glow-hi));border-radius:4px}
.ubar.hot>i{background:var(--warn-txt)}

/* No min-width: it existed to line the pager up with the table's 720px floor,
   and now that the table scrolls inside .dtable-wrap the pager is the only
   thing left forcing the page sideways. It wraps instead. */
.pager{display:flex;align-items:center;justify-content:space-between;gap:10px;
      flex-wrap:wrap;padding:14px 20px;
      border-top:1px solid var(--bd);background:var(--warm-bg)}
.pager-info{font-size:13px;color:var(--bl-m);font-weight:500}
.pager-ctrls{display:flex;gap:6px;align-items:center}
.pager-btn{font-size:13px;font-weight:700;min-width:34px;height:34px;padding:0 12px;
      border:1.5px solid var(--bd);background:var(--w);border-radius:8px;cursor:pointer;color:var(--ink)}
.pager-btn:hover:not(:disabled){border-color:var(--ink)}
.pager-btn.on{background:var(--orange);border-color:var(--orange);color:#fff}
.pager-btn:disabled{opacity:.45;cursor:default}

/* ==========================================================================
   Modals, drawers, forms
   ========================================================================== */
.dmodal{position:fixed;inset:0;background:rgba(15,25,35,.5);display:none;align-items:center;
      justify-content:center;z-index:9999;padding:24px}
.dmodal.open{display:flex}
.dmodal-c{background:var(--w);border-radius:var(--r-modal);width:100%;max-width:580px;max-height:90vh;
      overflow:auto;box-shadow:0 24px 60px rgba(15,25,35,.3)}
.dmodal-c.wide{max-width:760px}
.dmodal-c.narrow{max-width:440px}
.dmodal-h{display:flex;align-items:center;justify-content:space-between;padding:22px 26px;
      border-bottom:1px solid var(--bd)}
.dmodal-t{font-size:20px;font-weight:800;color:var(--ink)}
.dmodal-x{width:34px;height:34px;border-radius:9px;border:1px solid var(--bd);background:var(--w);
      cursor:pointer;font-size:18px;color:var(--bl-m);display:flex;align-items:center;justify-content:center}
.dmodal-x:hover{border-color:var(--ink);color:var(--ink)}
.dmodal-b{padding:24px 26px}
.dmodal-f{display:flex;justify-content:flex-end;gap:10px;padding:18px 26px;border-top:1px solid var(--bd)}

.seg{display:flex;gap:4px;padding:4px;background:var(--gb);border:1px solid var(--bd);
      border-radius:11px;margin-bottom:24px}
.seg button{flex:1;font-size:13px;font-weight:700;color:var(--bl-m);background:none;border:none;
      border-radius:8px;padding:10px;cursor:pointer}
.seg button.on{background:var(--w);color:var(--orange);box-shadow:0 1px 4px rgba(15,25,35,.08)}

.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.ff{display:flex;flex-direction:column;gap:6px}
.ff.full{grid-column:1/-1}
.ff label{font-size:12px;font-weight:700;color:var(--ink);letter-spacing:.2px}
.ff input,.ff select,.ff textarea{font-family:inherit;font-size:14px;color:var(--ink);
      border:1.5px solid var(--bd);border-radius:var(--r-ctl);padding:11px 13px;background:var(--warm-bg);outline:none}
.ff input:focus,.ff select:focus,.ff textarea:focus{border-color:var(--orange);background:var(--w)}
.ff .err{font-size:11.5px;color:var(--rd-txt);font-weight:600}
.ff input.invalid,.ff select.invalid{border-color:var(--rd-txt)}
.phone-row{display:flex;gap:8px}
.phone-row select{flex:0 0 108px}
.phone-row input{flex:1}
.form-error{background:var(--rd-soft);color:var(--rd-txt);border:1px solid rgba(180,54,47,.25);
      border-radius:var(--r-ctl);padding:11px 14px;font-size:13px;font-weight:600;margin-bottom:16px}

.fbackdrop{position:fixed;inset:0;background:rgba(15,25,35,.4);z-index:10001;opacity:0;
      pointer-events:none;transition:opacity .2s}
.fbackdrop.open{opacity:1;pointer-events:auto}
/* SLID OFF-SCREEN *AND* HIDDEN, and the second half is not belt-and-braces.
   `transform` moves the panel out of view but keeps it painting, and this one
   casts its shadow LEFTWARDS — `-12px` with a 40px blur — so a closed drawer
   laid a grey band down the right-hand edge of the page, on top of the content.
   Seven of these render on the admin panel (one per filterable table) and every
   one contributed its own shadow to the same 52px strip, which is why it read
   as a deliberate gradient rather than a stray shadow.

   IT WAS ALSO 48 CONTROLS IN THE TAB ORDER. `transform` does not take an
   element out of the focus order, so tabbing across the admin page walked into
   seven invisible filter panels — every select, input and Reset button in them.
   `visibility:hidden` is what fixes both, which is why it is the tool used here
   rather than dropping the shadow: a shadow-only fix would have left a keyboard
   user trapped in a panel they cannot see.

   THE DELAY IS WHAT KEEPS THE ANIMATION. Hiding on the same tick as the
   transform would make the drawer vanish instead of sliding away, so
   `visibility` transitions with a zero duration and a delay equal to the slide
   — it flips at the END of the close, and immediately (no delay) on open. Both
   states set `transition` in full: inheriting the closed delay would hold a
   drawer invisible for the whole of its opening slide. */
.fdrawer{position:fixed;top:0;right:0;height:100vh;width:360px;background:var(--w);z-index:10002;
      box-shadow:-12px 0 40px rgba(15,25,35,.18);display:flex;flex-direction:column;
      transform:translateX(100%);visibility:hidden;
      transition:transform .24s cubic-bezier(.4,0,.2,1),visibility 0s .24s}
.fdrawer.open{transform:translateX(0);visibility:visible;
      transition:transform .24s cubic-bezier(.4,0,.2,1),visibility 0s 0s}
.fdrawer-h{display:flex;align-items:center;justify-content:space-between;padding:22px 24px;
      border-bottom:1px solid var(--bd)}
.fdrawer-h .t{font-size:19px;font-weight:800;color:var(--ink)}
.fdrawer-b{flex:1;overflow:auto;padding:22px 24px;display:flex;flex-direction:column;gap:22px}
.fgroup{display:flex;flex-direction:column;gap:8px}
.fgroup>label{font-size:12px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--bl-m)}
.fgroup select,.fgroup input{font-family:inherit;font-size:14px;font-weight:600;color:var(--ink);
      border:1.5px solid var(--bd);border-radius:var(--r-ctl);padding:11px 13px;background:var(--w);outline:none}
.fgroup select:focus,.fgroup input:focus{border-color:var(--orange)}
.fdrawer-f{display:flex;gap:10px;padding:18px 24px;border-top:1px solid var(--bd)}
.fdrawer-f>*{flex:1;justify-content:center}

/* ==========================================================================
   Toasts — the app's only notification surface
   ========================================================================== */
.toast-stack{position:fixed;bottom:28px;right:18px;z-index:10050;display:flex;flex-direction:column;
      gap:8px;pointer-events:none}
.toast{display:flex;align-items:flex-start;gap:11px;background:var(--ink);color:#fff;border-radius:10px;
      padding:12px 16px 12px 14px;box-shadow:0 16px 36px rgba(15,25,35,.32);min-width:280px;max-width:380px;
      animation:toastSlide .25s cubic-bezier(.22,.61,.36,1);pointer-events:auto;border-left:3px solid var(--orange)}
.toast.success{border-left-color:var(--gr)}
.toast.error{border-left-color:var(--rd)}
.toast-body{flex:1;min-width:0}
.toast-t{font-size:13px;font-weight:800;color:#fff;line-height:1.3;margin-bottom:2px}
.toast-d{font-size:11.5px;font-weight:500;color:rgba(255,255,255,.72);line-height:1.45}
.toast-x{background:transparent;border:none;color:rgba(255,255,255,.5);cursor:pointer;padding:2px;
      margin-left:4px;flex-shrink:0}
.toast-x:hover{color:#fff}
@keyframes toastSlide{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:translateX(0)}}

/* Loading state shared by every list */
.loading-row{padding:36px;text-align:center;color:var(--bl-m);font-size:14px}
.spinner{display:inline-block;width:16px;height:16px;border:2px solid var(--bd);
      border-top-color:var(--orange);border-radius:50%;animation:spin .7s linear infinite;
      vertical-align:-3px;margin-right:8px}
@keyframes spin{to{transform:rotate(360deg)}}
/* The same wait, inside a button that is waiting on a round trip. Its own class
   rather than `.spinner` above, because that one is sized and coloured for a
   list's loading row — a fixed border colour and a right margin — and a fixed
   colour inside a button disappears the moment the button is not the shade it
   was written against. `currentColor` takes the button's own text colour, so it
   reads on the white-on-orange `.btn-primary` and on the dark-on-gold
   `.auth-submit` without either of them knowing about the other. */
.btn-spinner{display:inline-block;width:14px;height:14px;border:2px solid currentColor;
      border-right-color:transparent;border-radius:50%;animation:spin .7s linear infinite;
      opacity:.8;flex:none}

/* ==========================================================================
   Profile cards (customer profile page)
   ========================================================================== */
.prof-hero{display:flex;align-items:center;gap:20px;background:var(--w);border:1px solid var(--bd);
      border-radius:16px;padding:26px;margin-bottom:22px}
.prof-av{width:76px;height:76px;border-radius:18px;display:flex;align-items:center;justify-content:center;
      font-size:26px;font-weight:800;color:#fff;flex-shrink:0;
      background:linear-gradient(135deg,#0F1923,#152230)}
.prof-name{font-size:26px;font-weight:800;color:var(--ink);letter-spacing:-.4px}
.prof-meta{font-size:14px;color:var(--bl-m);margin-top:5px}
.pcards{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:22px}
.pcard{background:var(--w);border:1px solid var(--bd);border-radius:var(--r-card);padding:22px 24px}
.pcard-t{font-size:12px;font-weight:800;letter-spacing:1.2px;text-transform:uppercase;
      color:var(--orange);margin-bottom:14px}
.prow{display:flex;justify-content:space-between;gap:16px;padding:11px 0;
      border-bottom:1px solid var(--bl-l);font-size:14px}
.prow:last-child{border-bottom:none}
.prow .k{color:var(--bl-m)}
.prow .v{color:var(--ink);font-weight:600;text-align:right}

/* "THIS NUMBER IS A CREDIT, NOT A CHARGE." One modifier, wherever it is hung.
   `.apr-pred-v.g` above dressed the tile and nothing else did, so the ledger's
   own refund cell — which has carried `g` since it was written — rendered in
   the default ink and a refund read as another charge that happened to have a
   minus sign.

   EVERY CELL IT IS PUT ON IS NAMED, rather than left to source order. They are
   all styled by TWO-PART selectors — `.dtable td`, `.prow .v`, `.dt-sub` inside
   a table — so a bare `.g` loses the cascade to every one of them however late
   it is declared. Declaring it late was the first attempt and changed nothing
   on screen. */
.g,.dtable td.g,.dtable .dt-sub.g,.prow .v.g{color:var(--gr-txt)}

@media (max-width:1100px){
  .apr-preds{grid-template-columns:repeat(2,1fr);gap:18px 0}
  .apr-pred:nth-child(3){padding-left:0;border-left:none}
  .pcards{grid-template-columns:1fr}
}
/* ── The mobile shell ────────────────────────────────────────────────────────
   The sidebar used to be display:none below 820px. It is the only navigation
   in the product, so that left a phone with no way to reach Team, Profile or
   any admin view — the header user-menu was the only thing still reachable.
   It is now an off-canvas drawer instead: same element, same nav_items, slid
   out of frame and brought back by the header button.

   Hidden from assistive tech as well as sight when closed. `visibility` is
   what does that; the transform alone would leave the links focusable behind
   the content, so tabbing would walk into a nav nobody can see. */
.side-toggle{display:none;align-items:center;justify-content:center;
      width:38px;height:38px;margin-right:2px;padding:0;flex:0 0 auto;
      background:none;border:1px solid var(--bd);border-radius:9px;
      color:var(--ink);cursor:pointer;transition:background .12s,color .12s}
.side-toggle:hover{background:var(--gb);color:var(--orange)}
.side-toggle:focus-visible{outline:2px solid var(--orange);outline-offset:1px}
.side-scrim{display:none}

@media (max-width:820px){
  .side{
    position:fixed;top:0;left:0;bottom:0;z-index:10001;
    width:min(280px,86vw);max-width:100%;
    transform:translateX(-100%);visibility:hidden;
    transition:transform .22s ease,visibility .22s;
    box-shadow:0 0 40px rgba(15,25,35,.18);
  }
  .side.open{transform:none;visibility:visible}
  .side-scrim{display:block;position:fixed;inset:0;z-index:10000;
      background:rgba(15,25,35,.45)}
  .side-toggle{display:flex}

  .content{padding:0 16px 16px}
  .jr-toolbar{flex-direction:column;align-items:stretch}
  .jr-search{flex:1 1 auto}
  .fgrid{grid-template-columns:1fr}

  /* The header has to fit a menu button, a title and the user pill. The email
     under the name is the first thing to go — it is duplicated inside the menu
     the pill opens. */
  .tophd{padding-left:16px;padding-right:16px;gap:10px}
  .tophd-title{font-size:17px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .search{height:36px;padding-left:11px}
  .search .kbd{display:none}
  .user-name span:last-child{display:none}
  .user-name{min-width:0}

  /* A drawer wider than the screen is a drawer with a cut-off close button. */
  .fdrawer{width:min(360px,100%)}
}

/* Reduced motion: the drawer must still open, it just must not slide. */
@media (prefers-reduced-motion:reduce){
  .side{transition:none}
}

@media (max-width:560px){
  /* Stat strips: two columns of a four-column grid still reads as a table of
     numbers at 360px, and the dividers between them stop lining up. */
  .apr-preds{grid-template-columns:1fr}
  .apr-pred{padding-left:0;border-left:none}

  .content{padding:0 12px 12px}
  .tophd{height:auto;min-height:64px;padding-top:10px;padding-bottom:10px}
  .user-name{display:none}          /* the avatar alone opens the same menu */
  .dmodal{padding:12px}
  .dmodal-h,.dmodal-b,.dmodal-f{padding-left:16px;padding-right:16px}
  .dmodal-t{font-size:17px}
  .dmodal-f{flex-wrap:wrap}
  .dmodal-f>*{flex:1 1 auto}
}

/* ── Show/hide password ──────────────────────────────────────────────────────
   The wrapper and button are injected by ui.js around every password input, so
   these rules have to hold on both the light app surfaces and the dark auth
   ones. The button inherits `color`, and each surface sets its own below. */
.pw-wrap{position:relative;display:block;width:100%}
.pw-wrap input{width:100%;padding-right:42px}
.pw-toggle{
  position:absolute;top:50%;right:8px;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;
  background:none;border:none;border-radius:7px;cursor:pointer;
  color:var(--bl-m);opacity:.75;transition:opacity .12s,color .12s,background .12s;
}
.pw-toggle:hover{opacity:1;color:var(--orange);background:rgba(173,101,44,.08)}
.pw-toggle:focus-visible{outline:2px solid var(--orange);outline-offset:1px;opacity:1}
/* Dark auth surfaces: signup, set-password, the error pages. */
.auth-screen .pw-toggle{color:#B7A68F}
.auth-screen .pw-toggle:hover{color:var(--orange-glow-hi);background:rgba(212,154,94,.12)}

/* Workspace picker in the user menu — only shown to accounts in more than one. */
.user-menu-label{font-size:10.5px;font-weight:700;letter-spacing:1px;text-transform:uppercase;
        color:var(--muted-ink);padding:8px 14px 4px}
.user-menu-item.on{color:var(--orange)}
.user-menu-item.on svg{stroke:var(--orange)}
