/* DADCARE Mother App visual system.

   This stylesheet is scoped strictly to Mother App surfaces (Home, Apps, Inbox,
   Me, Post, the public listing page, and the authentication pages that share
   the shell chrome). Every rule is guarded by `body.shell`; My Business at
   /app/ deliberately renders on a plain <body> and therefore inherits nothing
   from this file. That separation is the Owner boundary — the operational
   surfaces of My Business must keep their own visual ground in this checkpoint.

   Tokens are re-declared here rather than overwritten in dadcare.css so global
   brand identity remains untouched. What Mother App gets is a scoped overlay:
   the same variable names, resolved to the DADCARE blue-and-cream family on
   these surfaces only. */

body.shell {
  /* DADCARE brand blue, warm-cream page ground. */
  --brand: #0F5FA6;
  --brand-dark: #0A3F72;
  --brand-soft: #DCEBF7;
  --on-brand: #ffffff;

  --bg: #FBF5EA;
  --surface: #ffffff;
  --surface-2: #F4EDDD;
  --border: #E8DFCA;

  --text: #0B2545;
  --muted: #5E6B7E;

  /* Sale-type accents. Colour never carries meaning alone — every badge is
     also labelled — but keeping the two families distinct makes a grid readable
     at a glance. Cool blue for retail, warm amber for wholesale. */
  --retail: #0F5FA6;
  --retail-soft: #DCEBF7;
  --retail-ink: #0A3F72;
  --wholesale: #B47207;
  --wholesale-soft: #F7E9CE;
  --wholesale-ink: #7A4E04;

  /* WhatsApp is a partner brand. The green is used exclusively for the
     WhatsApp action; nothing else in the shell is allowed to look like it. */
  --whatsapp: #25D366;
  --whatsapp-dark: #128C7E;
  --whatsapp-ink: #ffffff;

  /* Media overlay ink — the token used by the video pill and any element
     that sits on a picture and needs to keep contrast against unknown pixels.
     A photograph is not themed; this stays constant in both themes on purpose. */
  --on-media: #ffffff;
  --media-scrim: rgba(11, 37, 69, .78);

  /* Positive status pill (the ACTIVE mini-app badge). A slightly warmer green
     than --ok so it sits on the warm cream without vibrating. */
  --status-ok-bg: #E4F4E1;
  --status-ok-ink: #226C2E;

  /* Card and header shadow ink. One place to change the depth of every
     Mother App surface — used through box-shadow with rgba(var(--…)). */
  --shell-shadow: 11, 37, 69;
}

/* Dark mode carries the DADCARE blue at a lifted lightness. The warm-cream
   surface belongs to the light theme by design; in dark the ground stays the
   existing shell dark so contrast survives and photographs read honestly. */
html[data-theme="dark"] body.shell {
  --brand: #7EB7EA;
  --brand-dark: #A6CFF0;
  --brand-soft: #163049;
  --on-brand: #0A1626;

  --retail: #7EB7EA;
  --retail-soft: #163049;
  --retail-ink: #C3DEF3;
  --wholesale: #E7B15A;
  --wholesale-soft: #2E230F;
  --wholesale-ink: #F5D69A;

  --status-ok-bg: #163A1D;
  --status-ok-ink: #7DD98A;
}
/* ── END TOKENS ── everything below is scoped structural CSS that uses the
   variables declared above. No literal colour after this line. */

/* ── Page ground ──────────────────────────────────────────────────────────
   The shell paints its own body colour so the warm cream reaches the safe
   areas on mobile without a second declaration per page. */
body.shell { background: var(--bg); color: var(--text); }

/* ── Header brand mark ────────────────────────────────────────────────────
   The brand text stays as it was — the mark is a small circular blue "D"
   placed before it, so the wordmark keeps the same address on the page and a
   reader who has never seen a logo before still reads "DADCARE". */
body.shell .mk-top {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
body.shell .mk-brand { display: inline-flex; align-items: center; gap: 10px; }
body.shell .mk-brand .mk-mono {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 12px;
  background: var(--brand); color: var(--on-brand);
  font-weight: 800; font-size: 16px; letter-spacing: .02em;
}
body.shell .mk-brand .mk-word {
  font-weight: 800; letter-spacing: .04em; color: var(--text);
  font-size: 18px;
}

/* ── Search field ─────────────────────────────────────────────────────────
   A little taller, so the field itself is the visual anchor of the page. */
body.shell .mksearch input {
  min-height: 52px; padding: 12px 16px 12px 44px; font-size: 16px;
  border-radius: 999px; background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}
body.shell .mksearch .ic { left: 14px; width: 22px; height: 22px; }
body.shell .mksearch input:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 1px;
}

/* ── Category chips ───────────────────────────────────────────────────────
   Larger touch target and a rounder pill so a chip reads as a control, not a
   badge. The default chip sits on the page ground; the selected chip fills
   with DADCARE blue. */
body.shell .chiprow .chip {
  padding: 9px 18px; min-height: 40px; font-size: 14px; font-weight: 600;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); border-radius: 999px;
}
body.shell .chiprow .chip.on {
  background: var(--brand); border-color: var(--brand);
  color: var(--on-brand);
}

/* ── Narrow-phone grid contract ──────────────────────────────────────────
   Two rules used to disagree here. shell.css collapsed the grid to one
   column below 360px; this file overrode it back to two at every mobile
   width. Both were column counts written against the viewport, and neither
   was measured against the card that had to fit inside one.

   Measured, they disagree because they are each right somewhere. With the
   12px gutters below and an 8px gap, a 320px screen leaves the grid 296px:
   two columns make a 140px card, under the 152px this card needs before its
   price starts losing digits to an ellipsis. The same arithmetic at 359px
   leaves 335px, and two columns make a 163px card, which is comfortably
   over it.

   So neither count is stated any more. shell.css asks for as many columns of
   at least `--pcard-min` as there is room for, and that answers 320px with
   one column and 359px with two — the outcome each of the old rules was
   reaching for, decided by the width actually available rather than by a
   breakpoint. Only the gap and the gutters stay here, because those are what
   keep a narrow screen from scrolling sideways.

   The card body keeps its two pixels of horizontal padding and the smaller
   type below, so the title, price and WhatsApp action keep their readable
   widths where the screen is genuinely small. */
@media (max-width: 359px) {
  body.shell .pgrid { gap: 8px; }
  body.shell main.wrap { padding-left: 12px; padding-right: 12px; }
  /* The chip row deliberately bleeds to the page edge via a negative margin
     in shell.css. On the very narrow widths the page gutter shrinks to 12px,
     so the bleed has to shrink with it — otherwise the strip overshoots the
     viewport by the 4px difference and the document scrolls sideways. */
  body.shell .chiprow { margin-left: -12px; margin-right: -12px;
    padding-left: 12px; padding-right: 12px; }
  body.shell .pcard-body { padding: 8px 10px 10px; }
  body.shell .pcard-name { font-size: 13px; }
  body.shell .pcard-price { font-size: 15px; }
  /* `margin-top: auto` is restated after each shorthand: the shorthand resets
     it, and it is what holds the action at the foot of the card. */
  body.shell .pcard-wa {
    margin: 8px 10px 10px; margin-top: auto; min-height: 36px; font-size: 12px;
    padding: 6px 8px;
  }
  body.shell .pcard-wa-slot {
    margin: 8px 10px 10px; margin-top: auto; min-height: 36px;
  }
  body.shell .pcard-wa .ic { width: 14px; height: 14px; }
  body.shell .pcard-kind { font-size: 10px; padding: 3px 8px; }
}

/* ── Product card polish ──────────────────────────────────────────────────
   The card stays as it was in structure — media, then words, then one action.
   What changes: a slightly larger radius so the shadow looks intentional, a
   soft shadow instead of a hard border on hover, and sale-type badge variants
   that separate retail from wholesale without either becoming decorative. */
body.shell .pcard {
  border-radius: 20px; border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
  background: var(--surface);
}
@media (hover: hover) {
  body.shell .pcard:hover {
    border-color: var(--brand);
    box-shadow: 0 4px 14px rgba(11, 37, 69, .08);
  }
}
body.shell .pcard-media { background: var(--surface-2); }

/* Sale-type variants. The base .pcard-kind rule from shell.css remains — this
   only re-paints it and adds two modifiers, so an unknown sale type falls back
   to the neutral chip rather than looking like one of the two. */
body.shell .pcard-kind {
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; font-size: 11px; padding: 4px 10px;
  box-shadow: 0 1px 2px rgba(11, 37, 69, .06);
}
body.shell .pcard-kind.retail {
  background: var(--retail-soft); border-color: var(--retail-soft);
  color: var(--retail-ink);
}
body.shell .pcard-kind.wholesale {
  background: var(--wholesale-soft); border-color: var(--wholesale-soft);
  color: var(--wholesale-ink);
}

body.shell .pcard-video {
  background: var(--media-scrim); border-color: transparent; color: var(--on-media);
}
body.shell .pcard-video .ic { color: var(--on-media); }

/* The price. The deeper brand-ink blue is the loudest thing in the card. */
body.shell .pcard-price {
  font-size: 17px; font-weight: 800; color: var(--brand-dark);
}
body.shell .pcard-price .cur {
  color: var(--brand-dark); opacity: .82; margin-right: 4px;
  font-size: 12px; font-weight: 700;
}

/* Location line with a small pin. The pin is rendered by the template inside
   .pcard-where; here it just gets sized and coloured. */
body.shell .pcard-where {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted); font-size: 12px;
}
body.shell .pcard-where .ic { width: 14px; height: 14px; flex: none; color: var(--muted); }
body.shell .pcard-pin {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); flex: none;
}
body.shell .pcard-pin .ic { width: 14px; height: 14px; }

/* WhatsApp call-to-action. Filled green, white type, WhatsApp glyph. Only
   this button is allowed to look this way; nothing else in the shell borrows
   the partner colour. */
body.shell .pcard-wa {
  background: var(--whatsapp); border-color: var(--whatsapp);
  color: var(--whatsapp-ink); font-weight: 700;
  border-radius: 999px; min-height: 42px; font-size: 14px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
/* The reserved foot matches the themed button's height, so a listing with no
   WhatsApp number holds exactly the room one would have taken. */
body.shell .pcard-wa-slot { min-height: 42px; }
body.shell .pcard-wa:active { background: var(--whatsapp-dark); border-color: var(--whatsapp-dark); }
body.shell .pcard-wa .ic { width: 18px; height: 18px; color: var(--whatsapp-ink); }
@media (hover: hover) {
  body.shell .pcard-wa:hover { background: var(--whatsapp-dark); border-color: var(--whatsapp-dark); }
}

/* ── Section heading ────────────────────────────────────────────────────── */
body.shell .mksection {
  font-size: 20px; font-weight: 800; color: var(--text);
  margin: 14px 0 12px; letter-spacing: -.005em;
}
body.shell .mksection .count { color: var(--muted); font-weight: 600; font-size: 14px; }

/* ── Bottom navigation ────────────────────────────────────────────────────
   The raised central "+" grows a little and gets a white ring so it sits
   above the tab strip rather than in it. Nothing about the destinations
   changes; the strip is still Home | Apps | + | Inbox | Me. */
body.shell .globalnav {
  background: var(--surface); border-top: 1px solid var(--border);
  box-shadow: 0 -1px 0 rgba(11, 37, 69, .04);
}
body.shell .globalnav a.active { color: var(--brand); background: transparent; }
body.shell .globalnav a.active .ic { color: var(--brand); }

body.shell .globalnav a.post { position: relative; }
body.shell .globalnav a.post .postmark {
  width: 52px; height: 52px; border-radius: 999px;
  background: var(--brand); color: var(--on-brand);
  font-size: 30px; font-weight: 400; line-height: 1;
  box-shadow: 0 0 0 4px var(--surface), 0 6px 14px rgba(11, 37, 69, .18);
  margin-top: -22px;
}

/* ── Card containers used across Apps, Inbox, Me ───────────────────────── */
body.shell .card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; padding: 18px;
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}

/* Rows in Me / Inbox use the same card treatment for a consistent surface. */
body.shell .row {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 16px; padding: 14px; min-height: 60px;
}

/* Apps and Me list-row leading glyph, kept from shell.css but re-toned to
   read on the warm cream. */
body.shell .app-ico { background: var(--brand-soft); color: var(--brand); }
body.shell .app-ico .ic { color: var(--brand); }
body.shell .a-business { background: var(--brand-soft); color: var(--brand); }

/* ── Section titles on Apps, Inbox, Me ─────────────────────────────────── */
body.shell .section {
  font-size: 28px; font-weight: 800; color: var(--text);
  text-transform: none; letter-spacing: -.01em;
  margin: 8px 0 4px;
}
body.shell .section + .hint,
body.shell h2.section + p.hint { color: var(--muted); font-size: 15px; margin-bottom: 14px; }

/* ── The "tile" cards used by Apps' active workspace and Me's rows ─────── */
body.shell .tile {
  display: flex; align-items: center; gap: 14px;
  padding: 16px; border-radius: 20px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text); box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
  min-height: 76px; text-decoration: none;
}
body.shell .tile .grow { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
body.shell .tile .name { font-size: 16px; font-weight: 700; color: var(--text); }
body.shell .tile .meta { font-size: 13px; color: var(--muted); }
body.shell .tile .app-ico {
  width: 48px; height: 48px; border-radius: 14px; margin: 0;
  background: var(--brand-soft); color: var(--brand);
}
body.shell .tile .app-ico .ic { color: var(--brand); }
body.shell .tile .status {
  padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
}
body.shell .tile .status.ok { background: var(--status-ok-bg); color: var(--status-ok-ink); }
body.shell .tile .status.locked {
  background: var(--surface-2); color: var(--muted);
}

/* Locked / coming-soon rows: dashed border and a lock glyph. These are only
   used by the honest signed-out / no-registered-mini-app states. */
body.shell .tile.locked {
  background: transparent; border-style: dashed; border-color: var(--border);
  box-shadow: none;
}
body.shell .tile.locked .app-ico { background: var(--surface-2); color: var(--muted); }

/* ── Business-context actions ────────────────────────────────────────────
   A business may carry an action that is NOT a mini-app — today the
   Stakeholder Dashboard, for a visitor who has an approved investment in
   the business whose tile this is. It sits alongside that one tile rather
   than becoming a tile of its own, so the business keeps a single
   presentation and the relationship is never mistaken for an installed app. */
body.shell .ctx-row { display: flex; align-items: stretch; gap: 10px; }
body.shell .ctx-row > .tile { flex: 1; min-width: 0; }

/* One action per approved relationship. A visitor may be both Partner and
   Sponsor in the same business — two Stakeholder rows, two dashboards — so
   the business is presented once and stacks its actions here rather than
   appearing twice. */
body.shell .ctx-actions {
  display: flex; flex-direction: column; justify-content: center;
  gap: 6px; flex: none; min-width: 0;
}
body.shell .ctx-action {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; padding: 10px 16px; min-height: var(--tap);
  border-radius: 14px; background: var(--surface);
  border: 1px solid var(--border); color: var(--text);
  font-size: 14px; font-weight: 700; text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}
body.shell .ctx-action:active { background: var(--surface-2); }

/* A business the visitor has invested in but does not work at. Deliberately
   NOT the .tile treatment: no accent, no mini-app glyph, no "Active" chip —
   this is a relationship, and it must not read as an app in the launcher. */
body.shell .ctx-stake {
  display: flex; align-items: center; gap: 14px;
  padding: 16px; border-radius: 20px; min-height: 68px;
  background: transparent; border: 1px dashed var(--border);
  color: var(--text); text-decoration: none;
}
body.shell .ctx-stake + .ctx-stake { margin-top: 10px; }
body.shell .ctx-stake .grow {
  display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0;
}
body.shell .ctx-stake .name { font-size: 16px; font-weight: 700; }
body.shell .ctx-stake .meta { font-size: 13px; color: var(--muted); }
body.shell .ctx-stake .ctx-actions { flex-direction: row; flex-wrap: wrap; }

/* ── Me profile card ─────────────────────────────────────────────────────
   The identity block on Me: initials avatar, then the account name, then the
   email/handle underneath. No fabricated city or currency. */
body.shell .profile-card {
  display: flex; align-items: center; gap: 16px; padding: 20px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}
body.shell .profile-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 62px; height: 62px; border-radius: 18px;
  background: var(--brand); color: var(--on-brand);
  font-size: 22px; font-weight: 800; letter-spacing: .04em;
  flex: none;
}
body.shell .profile-name { font-size: 20px; font-weight: 800; color: var(--text); margin: 0; }
body.shell .profile-sub { color: var(--muted); font-size: 14px; margin: 2px 0 0; }

/* ── Me menu card: a group of related rows with divider lines. ─────────── */
body.shell .me-menu {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 20px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}
body.shell .me-menu > a,
body.shell .me-menu > .row {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px; min-height: 60px;
  border: 0; border-radius: 0; background: transparent;
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid var(--border);
}
body.shell .me-menu > a:last-child,
body.shell .me-menu > .row:last-child { border-bottom: 0; }
/* A menu row that acts instead of navigating. Same row, same divider, same
   spacing as its neighbours — a <button> simply does not inherit the three
   things a <div> never had to be told. */
body.shell .me-menu > button.row {
  width: 100%; font: inherit; text-align: left; cursor: pointer;
}
body.shell .me-menu .app-ico {
  width: 40px; height: 40px; border-radius: 12px; margin: 0;
  background: var(--brand-soft); color: var(--brand);
}
body.shell .me-menu .app-ico .ic { color: var(--brand); }
body.shell .me-menu .name { font-size: 16px; font-weight: 700; }
body.shell .me-menu .meta { font-size: 13px; color: var(--muted); margin-top: 2px; }
body.shell .me-menu .caret { color: var(--muted); flex: none; }
body.shell .me-menu .caret .ic { width: 18px; height: 18px; }

/* ── Inbox row visual ────────────────────────────────────────────────────
   A leading glyph, a title in bold, a preview line in muted colour, and the
   time on the right. Renders whatever the notifications API actually returns;
   no invented content. */
body.shell .inbox-list { display: flex; flex-direction: column; gap: 10px; }
body.shell .inbox-item {
  display: flex; align-items: flex-start; gap: 14px;
  padding: 16px; border-radius: 18px; background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(11, 37, 69, .04);
}
body.shell .inbox-item .app-ico {
  width: 42px; height: 42px; border-radius: 12px; flex: none; margin: 0;
  background: var(--brand-soft); color: var(--brand);
}
body.shell .inbox-item .app-ico .ic { color: var(--brand); }
body.shell .inbox-item .grow { flex: 1; min-width: 0; }
body.shell .inbox-item .name { font-weight: 700; font-size: 15px; color: var(--text); }
body.shell .inbox-item .meta {
  color: var(--muted); font-size: 14px; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .inbox-item .time { color: var(--muted); font-size: 12px; flex: none; }

/* An honest "we cannot show your notifications right now" state. Not styled
   as an error — this is the ordinary case for a signed-in visitor who has no
   active business context yet, and lecturing them helps nobody. */
body.shell .inbox-unavailable {
  padding: 20px; border-radius: 18px;
  background: var(--surface); border: 1px dashed var(--border);
  color: var(--muted); font-size: 14px; line-height: 1.5;
}

/* ── Authentication surfaces ─────────────────────────────────────────────
   The login and register pages already live under body.shell via auth_base
   and pick up the palette automatically. What is added here is a stronger
   card treatment matching the approved DADCARE design language, and the
   circular padlock header used on the "Sign in to post" surface. */
body.shell .auth-wrap {
  max-width: 460px; margin: 0 auto; padding: 32px 18px 40px;
}
body.shell .auth-brand {
  display: inline-flex; align-items: center; gap: 10px;
  justify-content: center; width: 100%;
  color: var(--text); font-weight: 800; font-size: 20px;
  margin-bottom: 22px;
}
body.shell .auth-brand::before {
  content: "D";
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 12px;
  background: var(--brand); color: var(--on-brand);
  font-weight: 800; font-size: 16px;
}
body.shell .auth-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 24px; padding: 26px 22px;
  box-shadow: 0 6px 24px rgba(11, 37, 69, .06);
}
body.shell .auth-card h1 {
  font-size: 22px; font-weight: 800; margin: 0 0 4px; text-align: center;
}
body.shell .auth-card .auth-lede {
  color: var(--muted); text-align: center; font-size: 14px; line-height: 1.5;
  margin: 0 0 18px;
}
body.shell .auth-lock {
  display: inline-flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand);
  margin: 4px auto 12px;
}
body.shell .auth-lock .ic { width: 30px; height: 30px; color: var(--brand); }
body.shell .auth-card .btn { border-radius: 999px; min-height: 52px; font-size: 15px; }
body.shell .auth-alt { text-align: center; color: var(--muted); font-size: 14px; margin-top: 18px; }
body.shell .auth-alt a { color: var(--brand-dark); font-weight: 600; }

/* Divider between primary submit and secondary options on the auth card. */
body.shell .auth-divider {
  display: flex; align-items: center; gap: 12px;
  color: var(--muted); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; margin: 14px 0;
}
body.shell .auth-divider::before,
body.shell .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--border);
}

/* ── Public listing page: single ad view ─────────────────────────────────
   The SSR /p/<slug>/ page also lives on body.shell. Aligning the price and
   the WhatsApp CTA with the grid card keeps a buyer who arrived from a card
   inside the same visual system. */
body.shell .listing { max-width: 640px; margin: 0 auto; padding-top: 6px; }
body.shell .listingmedia {
  border-radius: 24px; border: 1px solid var(--border);
  background: var(--surface-2);
}
body.shell .postprice { color: var(--brand-dark); font-size: 26px; font-weight: 800; }
body.shell .postprice .cur { color: var(--brand-dark); opacity: .82; }
body.shell .tag {
  padding: 4px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase;
  background: var(--retail-soft); color: var(--retail-ink);
}
body.shell .tag.wholesale { background: var(--wholesale-soft); color: var(--wholesale-ink); }
body.shell .listing .card { border-radius: 20px; }
body.shell .listing .btn.wa {
  background: var(--whatsapp); border-color: var(--whatsapp);
  color: var(--whatsapp-ink); border-radius: 999px;
  min-height: 48px; font-weight: 700;
}
body.shell .listing .btn.wa:active {
  background: var(--whatsapp-dark); border-color: var(--whatsapp-dark);
}

/* ── Load-more and pagination affordances polished for the new page ground. */
body.shell #more.btn.secondary {
  background: var(--surface); color: var(--brand-dark); border-color: var(--border);
  border-radius: 999px;
}

/* ── Responsive fine-tuning ──────────────────────────────────────────────
   The grid already collapses to one column below 360px in shell.css; here
   the header just gets a little breathing room on very narrow phones. */
@media (max-width: 359px) {
  body.shell .mk-brand .mk-word { font-size: 16px; }
  body.shell .mk-brand .mk-mono { width: 30px; height: 30px; font-size: 14px; }
}

/* Desktop: one column of stacked full-width phones is not a desktop layout.
   The .pgrid rule in shell.css already widens to 3–4 columns; the header just
   needs the same maximum reading width. */
@media (min-width: 900px) {
  body.shell .mk-top {
    padding-left: 226px;
  }
  body.shell main.wrap {
    max-width: 1160px;
  }
}

/* ── Selling (/me/selling/) ───────────────────────────────────────────────
   The seller's own Marketplace posts. Prefixed `sell-` throughout so nothing
   here can reach the public card (`.pcard`) or the Me menu (`.me-menu`), which
   are different screens with different meanings. Colour comes from the tokens
   above and nowhere else. */

body.shell .sell-tabs {
  display: flex; gap: 8px; margin: 14px 0 4px;
}
body.shell .sell-tab {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 42px; padding: 8px 10px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--muted);
  font-size: 13px; font-weight: 700; cursor: pointer;
}
body.shell .sell-tab .ic { width: 17px; height: 17px; }
body.shell .sell-tab.on {
  background: var(--brand-soft); color: var(--brand); border-color: var(--brand);
}
body.shell .sell-tab:focus-visible {
  outline: 3px solid var(--brand); outline-offset: 2px;
}

/* Stated, not offered: the catalogue address does not exist yet, so this is a
   sentence rather than a control somebody could press. */
body.shell .sell-soon {
  display: flex; align-items: center; gap: 8px;
  margin: 12px 0 4px; padding: 10px 12px;
  border: 1px dashed var(--border); border-radius: var(--radius);
  background: var(--surface-2); color: var(--muted);
  font-size: 13px;
}
body.shell .sell-soon .ic { width: 17px; height: 17px; flex: none; }

body.shell .sell-list { display: grid; gap: 10px; margin-top: 14px; }
body.shell .sell-post {
  display: flex; gap: 12px; align-items: center;
  padding: 10px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface);
}
body.shell .sell-thumb {
  width: 62px; height: 62px; flex: none; overflow: hidden;
  border-radius: 10px; background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
}
body.shell .sell-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
body.shell .sell-thumb .noimage {
  font-size: 10px; color: var(--muted); text-align: center; padding: 0 4px;
}
body.shell .sell-body { flex: 1; min-width: 0; display: grid; gap: 2px; }
body.shell .sell-name {
  margin: 0; font-size: 15px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .sell-price { margin: 0; font-size: 15px; font-weight: 800; color: var(--text); }
body.shell .sell-price .cur { font-size: 11px; font-weight: 700; color: var(--muted); }
body.shell .sell-where {
  margin: 0; font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Secondary to the name, the price and the state: the seller's own view
   count, sized like the location line rather than the price. */
body.shell .sell-views {
  margin: 0; font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .sell-state {
  flex: none; align-self: flex-start;
  padding: 4px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  background: var(--surface-2); color: var(--muted);
}
body.shell .sell-state.live { background: var(--status-ok-bg); color: var(--status-ok-ink); }
body.shell .sell-state.private,
body.shell .sell-state.pending { background: var(--warn-soft); color: var(--warn); }
body.shell .sell-state.suspended,
body.shell .sell-state.rejected { background: var(--danger-soft); color: var(--danger); }

body.shell .sell-empty { margin-top: 14px; }

/* Owner controls. Compact and text-only: a post card is small, and four word
   buttons read better on a 320px screen than four icons nobody has learned. */
body.shell .sell-post { flex-wrap: wrap; }
body.shell .sell-actions {
  display: flex; flex-wrap: wrap; gap: 6px;
  width: 100%; margin-top: 2px;
}
body.shell .sell-act {
  min-height: 34px; padding: 6px 11px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text);
  font-size: 12.5px; font-weight: 700; cursor: pointer;
}
body.shell .sell-act:active { background: var(--surface-2); }
body.shell .sell-act.danger { color: var(--danger); border-color: var(--danger); }
body.shell .sell-act:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
body.shell .sell-act[disabled] { opacity: .55; cursor: not-allowed; }
body.shell .sell-post.working { opacity: .7; }

body.shell .sell-confirm {
  width: 100%; margin-top: 8px; padding: 11px 12px;
  border: 1px solid var(--danger); border-radius: var(--radius);
  background: var(--danger-soft);
}
body.shell .sell-confirm-title {
  margin: 0 0 4px; font-size: 14px; font-weight: 700; color: var(--text);
}
body.shell .sell-confirm .hint { margin: 0 0 8px; }

/* The edit form. Full-width inside the post card, one field per line: a small
   screen has no room for columns, and a seller correcting a price should not
   have to hunt for the box. */
body.shell .sell-edit {
  width: 100%; margin-top: 10px; padding: 12px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-2);
  display: grid; gap: 9px;
}
body.shell .sell-field { display: grid; gap: 4px; }
body.shell .sell-flabel {
  font-family: Archivo, sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--muted);
}
body.shell .sell-input {
  width: 100%; min-height: 42px; padding: 9px 11px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--text);
  font-size: 15px; font-family: inherit;
}
body.shell textarea.sell-input { min-height: 76px; resize: vertical; }
body.shell .sell-input:focus-visible {
  outline: 3px solid var(--brand); outline-offset: 1px; border-color: var(--brand);
}
body.shell .sell-edit .hint { margin: 0; }


/* ── The public catalogue (/s/<seller_id>/) ───────────────────────────────
   What a customer sees when a seller sends them a link. Its own `cat-` prefix
   throughout: this page is read by people with no DADCARE account, and it must
   not inherit or disturb anything the signed-in surfaces style. */

body.shell .cat-head {
  display: flex; gap: 13px; align-items: center;
  padding: 4px 0 14px; border-bottom: 1px solid var(--border); margin-bottom: 14px;
}
body.shell .cat-avatar {
  width: 52px; height: 52px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-soft); color: var(--brand);
  font-size: 21px; font-weight: 800;
}
body.shell .cat-name {
  margin: 0; font-size: 21px; font-weight: 800; color: var(--text);
  overflow-wrap: anywhere;
}
body.shell .cat-sub { margin: 2px 0 0; font-size: 14px; color: var(--muted); }

body.shell .cat-grid {
  display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 620px) {
  body.shell .cat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  body.shell .cat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

body.shell .cat-card {
  display: flex; flex-direction: column; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); overflow: hidden; color: inherit;
}
body.shell .cat-card:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }

body.shell .cat-media {
  position: relative; display: block; aspect-ratio: 1 / 1;
  background: var(--surface-2); overflow: hidden;
}
body.shell .cat-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
body.shell .cat-media .noimage {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; font-size: 12px; color: var(--muted);
}
body.shell .cat-kind {
  position: absolute; left: 7px; bottom: 7px;
  padding: 3px 8px; border-radius: 999px;
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
body.shell .cat-kind.retail { background: var(--brand-soft); color: var(--brand-dark); }
body.shell .cat-kind.wholesale { background: var(--wholesale-soft); color: var(--wholesale-ink); }

body.shell .cat-body { display: grid; gap: 2px; padding: 9px 11px 12px; min-width: 0; }
body.shell .cat-title {
  font-size: 14px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .cat-price { font-size: 15px; font-weight: 800; color: var(--text); }
body.shell .cat-price .cur { font-size: 11px; font-weight: 700; color: var(--muted); }
body.shell .cat-where {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .cat-empty { margin-top: 18px; }

/* Seller-side catalogue actions, on Selling. */
body.shell .sell-cat {
  display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0 4px;
}
body.shell .sell-cat .sell-act { flex: 1 1 auto; min-height: 40px; }

/* ── DADCARE Chat ────────────────────────────────────────────────────────
   The messaging surfaces, drawn in DADCARE's own palette and nobody else's.
   MARKETPLACE_PRODUCT_SPEC §7 is explicit that a WhatsApp *contact option*
   may carry WhatsApp's recognisable mark, but DADCARE Chat itself uses
   DADCARE's visual identity: the brand blue for what the reader said, the
   cream surface for what the other person said, and no borrowed green.

   Every colour below is a token from the palette at the top of this file, so
   the whole of it follows the theme the reader chose rather than restating
   light-mode values that go wrong in the dark. */

body.shell .chat-tabs {
  display: flex; flex-wrap: wrap; gap: 8px; row-gap: 8px; margin: 0 0 14px;
}
body.shell .chat-tab {
  /* The label stays on one line and the ROW wraps instead. Four tabs sharing
     one phone width used to shrink until each read as stacked fragments. */
  display: inline-flex; align-items: center; white-space: nowrap;
  min-height: var(--tap);
  padding: 8px 16px; border-radius: 999px; font-size: 14px; font-weight: 600;
  color: var(--muted); background: var(--surface-2);
  border: 1px solid var(--border); text-decoration: none;
}
body.shell .chat-tab.active {
  background: var(--brand); color: var(--on-brand); border-color: var(--brand);
}

body.shell .chat-row { text-decoration: none; color: inherit; }
body.shell .chat-avatar {
  width: 44px; height: 44px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand); color: var(--on-brand);
  font-weight: 700; font-size: 17px;
}
body.shell .chat-sub {
  font-size: 13px; color: var(--brand); margin-top: 1px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.shell .chat-you { color: var(--muted); font-weight: 600; }

/* Unread, on a conversation row. C4.4 MESSAGING unread and nothing to do with
   the notification inbox. The COUNT is the signal — a number that reads on its
   own — and the row carries a written sentence for a screen reader beside it,
   so the state never depends on seeing the brand fill. A row with nothing
   waiting renders none of this. */
body.shell .chat-aside {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: 6px; flex: none;
}
body.shell .chat-unread {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px;
  background: var(--brand); color: var(--on-brand);
  font-size: 12px; font-weight: 700; line-height: 1;
}
body.shell .chat-row.is-unread .name { font-weight: 800; }
body.shell .chat-row.is-unread .meta { color: var(--text); font-weight: 600; }

/* ── One conversation ─────────────────────────────────────────────────── */
body.shell .chat-head {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 0 14px; border-bottom: 1px solid var(--border);
}
body.shell .chat-back {
  width: var(--tap); height: var(--tap); flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text); text-decoration: none;
}
body.shell .chat-back:hover { background: var(--surface-2); }
body.shell .chat-name { font-weight: 700; font-size: 16px; color: var(--text); }
body.shell .chat-role { font-size: 13px; color: var(--muted); }

body.shell .chat-product {
  display: flex; align-items: center; gap: 12px; margin-top: 12px;
  padding: 12px 14px; border-radius: 14px; text-decoration: none;
  background: var(--brand-soft); border: 1px solid var(--border);
  color: var(--brand-dark);
}
body.shell .chat-product-t { font-weight: 650; font-size: 14px; }
body.shell .chat-product-p { font-size: 13px; margin-top: 2px; }

/* ── The thread, as one column ────────────────────────────────────────────
   The history is the only thing that scrolls. Header, product card, error and
   composer are fixed-size rows of the same flex column, so a composer that
   grows takes its space FROM the history instead of covering it. There is no
   constant clearance left to keep in step with anything. */
body.shell .chat-screen {
  /* What the page spends above and below this column: the sticky shell header
     (52px + its rule), the page's own 16px of padding top and bottom, and the
     78px bottom navigation. The safe-area inset is subtracted separately
     because the navigation adds it to its own height. */
  --chat-chrome: 163px;
  display: flex; flex-direction: column;
  height: calc(100vh - var(--chat-chrome));
  height: calc(100dvh - var(--chat-chrome) - env(safe-area-inset-bottom, 0px));
  min-height: 280px;
}
body.shell .chat-screen > .chat-head,
body.shell .chat-screen > .chat-product,
body.shell .chat-screen > .chat-error { flex: none; }

body.shell .chat-log {
  /* min-height:0 is what makes this scroll at all: without it a flex item
     refuses to shrink below its content and the overflow never happens. */
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 8px;
  padding: 16px 2px 12px;
}
body.shell .chat-bubble {
  max-width: min(78%, 520px); padding: 9px 13px 6px; border-radius: 16px;
  font-size: 15px; line-height: 1.42; word-wrap: break-word;
  overflow-wrap: anywhere;
}
body.shell .chat-bubble.mine {
  align-self: flex-end; background: var(--brand); color: var(--on-brand);
  border-bottom-right-radius: 5px;
}
body.shell .chat-bubble.theirs {
  align-self: flex-start; background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-bottom-left-radius: 5px;
}
body.shell .chat-text {
  margin: 0; white-space: pre-wrap; overflow-wrap: anywhere;
}
body.shell .chat-when {
  display: block; text-align: right; font-size: 11px; margin-top: 3px;
  opacity: .72;
}
body.shell .chat-empty {
  text-align: center; color: var(--muted); font-size: 14px;
  padding: 24px 16px;
}
body.shell .chat-error {
  margin-top: 12px; padding: 12px 14px; border-radius: 12px;
  background: var(--status-warn-bg, var(--surface-2));
  color: var(--status-warn-ink, var(--text)); font-size: 14px;
}

body.shell .chat-composer {
  /* IN FLOW, not fixed to the window. A fixed composer is the thing the iOS
     keyboard covers and the thing the desktop navigation rail runs underneath;
     as the last row of the thread's own column it is carried by the same
     layout as the history, so the keyboard scrolls it into view and the rail's
     gutter already applies to it. */
  position: static; flex: none;
  display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 0 8px;
  background: var(--surface); border-top: 1px solid var(--border);
}
body.shell .chat-composer textarea {
  flex: 1; resize: none; max-height: 120px; margin: 0;
  padding: 10px 14px; border-radius: 20px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text);
  /* 16px exactly. Mobile Safari zooms the page when a field smaller than this
     takes focus, and a zoomed thread cannot be scrolled back by itself. */
  font: inherit; font-size: 16px; line-height: 1.4;
}
body.shell .chat-send {
  width: 44px; height: 44px; flex: none; border: 0; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand); color: var(--on-brand); cursor: pointer;
}
body.shell .chat-send:disabled { opacity: .5; cursor: default; }

/* From the shell's own desktop breakpoint the navigation is a LEFT RAIL and
   `body.has-nav` has no bottom padding at all, so the column gets its height
   back and keeps a reading width rather than running to 1100px. */
@media (min-width: 900px) {
  body.shell .chat-screen {
    --chat-chrome: 85px;
    max-width: 720px;
  }
  body.shell .chat-bubble { max-width: min(72%, 460px); }
}

/* Paging controls — a row of ordinary links, because that is what they are.
   An unavailable one is still drawn, dimmed and marked `aria-disabled`, rather
   than vanishing: a control that disappears at the first and last page moves
   the one beside it under the reader's thumb. */
body.shell .chat-pager {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 10px; margin-top: 16px;
}
body.shell .chat-pager .hint { margin: 0; }
body.shell .chat-pager-off { opacity: .45; cursor: default; }

/* Older history sits ABOVE the log and newer below it, which is where they are
   in the conversation. Both are `flex: none` rows of the thread's own column,
   so the history keeps the rest of the height. */
body.shell .chat-screen > .chat-older,
body.shell .chat-screen > .chat-newer {
  flex: none; display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center; padding: 10px 0 2px;
}
body.shell .chat-screen > .chat-newer { padding: 2px 0 10px; }

body.shell .chat-start-card .postname { font-weight: 650; margin-top: 6px; }

/* The in-app route to the seller, on a product. Deliberately the brand
   button: inside DADCARE, DADCARE's own chat is the primary contact route and
   WhatsApp is the alternative beside it, not the other way round. */
body.shell .btn.chat-cta { background: var(--brand); color: var(--on-brand); }

/* ── Sponsor statement (/stake/investment/<id>/) — S3C1 ───────────────────
   Mobile-first, one column at phone width, a wider card grid on desktop.
   Tokens only: every colour below is a theme variable, so light and dark are
   both the design system's own values. Nothing here decides a figure — the
   page renders exact strings from the statement API. */
body.shell .sx { display: grid; gap: 14px; margin-top: 14px; min-width: 0; }
body.shell .sx > * { min-width: 0; }
body.shell .sx-head { display: flex; align-items: flex-start;
  justify-content: space-between; gap: 12px; }
body.shell .sx-head h3 { margin: 0; font-size: 18px; overflow-wrap: anywhere; }
body.shell .sx-head .hint { margin: 2px 0 0; }
body.shell .sx-banner { border-radius: 12px; padding: 12px 14px;
  border: 1px solid var(--border); }
body.shell .sx-banner strong { display: block; }
body.shell .sx-banner.is-active { background: var(--ok-soft); color: var(--ok);
  border-color: var(--ok-soft); }
body.shell .sx-banner.is-suspended { background: var(--warn-soft);
  color: var(--warn); border-color: var(--warn-soft); }
body.shell .sx-banner.is-inactive { background: var(--surface-2);
  color: var(--muted); }
body.shell .sx-net { background: var(--surface); border: 1px solid var(--border);
  border-radius: 16px; padding: 16px; }
body.shell .sx-net .sx-label { color: var(--muted); font-size: 13px; }
body.shell .sx-net .sx-big { font-size: 28px; font-weight: 700;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
  color: var(--text); margin-top: 4px; }
body.shell .sx-net .sx-cur { font-size: 15px; font-weight: 600;
  color: var(--muted); margin-right: 6px; }
body.shell .sx-grid { display: grid; gap: 10px;
  grid-template-columns: repeat(2, minmax(0, 1fr)); }
body.shell .sx-card { display: flex; flex-direction: column;
  justify-content: flex-start; align-items: stretch; width: 100%;
  text-align: left;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 14px; padding: 12px;
  font: inherit; cursor: pointer; min-width: 0; }
body.shell .sx-card:focus-visible { outline: 2px solid var(--brand);
  outline-offset: 2px; }
body.shell .sx-card .sx-label { color: var(--muted); font-size: 12px;
  display: block; }
body.shell .sx-card .sx-val { font-size: 16px; font-weight: 650;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
  display: block; margin-top: 4px; }
body.shell .sx-card .sx-sub { color: var(--muted); font-size: 12px;
  display: block; margin-top: 2px; overflow-wrap: anywhere; }
body.shell .sx-card.is-alert { border-color: var(--danger);
  background: var(--danger-soft); }
body.shell .sx-card.is-alert .sx-val { color: var(--danger); }
body.shell .sx-section { background: var(--surface);
  border: 1px solid var(--border); border-radius: 16px; padding: 14px; }
body.shell .sx-section h3 { margin: 0 0 10px; font-size: 15px; }
body.shell .sx-ranges { display: flex; gap: 6px; flex-wrap: wrap;
  margin-bottom: 10px; }
body.shell .sx-range { font: inherit; font-size: 13px; padding: 6px 12px;
  border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text); cursor: pointer; }
body.shell .sx-range[aria-pressed="true"] { background: var(--brand-soft);
  border-color: var(--brand); color: var(--brand-dark); font-weight: 600; }
body.shell .sx-chart { position: relative; width: 100%; }
body.shell .sx-chart svg { display: block; width: 100%; height: 190px;
  overflow: visible; }
body.shell .sx-chart svg:focus-visible { outline: 2px solid var(--brand);
  outline-offset: 4px; border-radius: 6px; }
body.shell .sx-grid-line { stroke: var(--border); stroke-width: 1; }
body.shell .sx-axis-text { fill: var(--muted); font-size: 11px;
  font-variant-numeric: tabular-nums; }
body.shell .sx-line { fill: none; stroke: var(--brand); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; }
body.shell .sx-area { fill: var(--brand); fill-opacity: .1; stroke: none; }
body.shell .sx-cross { stroke: var(--muted); stroke-width: 1; }
body.shell .sx-dot { fill: var(--brand); stroke: var(--surface);
  stroke-width: 2; }
body.shell .sx-tip { position: absolute; top: 0; pointer-events: none;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px;
  font-size: 12px; box-shadow: var(--shadow);
  white-space: nowrap; transform: translateX(-50%); }
body.shell .sx-tip strong { display: block; font-size: 14px;
  font-variant-numeric: tabular-nums; }
body.shell .sx-tabs { display: flex; gap: 4px; overflow-x: auto;
  scrollbar-width: thin; border-bottom: 1px solid var(--border);
  margin: 0 -2px 12px; padding: 0 2px; }
body.shell .sx-tab { font: inherit; font-size: 14px; white-space: nowrap;
  padding: 10px 12px; border: 0; background: none; color: var(--muted);
  border-bottom: 2px solid transparent; cursor: pointer; }
body.shell .sx-tab[aria-selected="true"] { color: var(--brand-dark);
  border-bottom-color: var(--brand); font-weight: 600; }
body.shell .sx-tab:focus-visible { outline: 2px solid var(--brand);
  outline-offset: -2px; }
body.shell .sx-rows { display: grid; gap: 0; }
body.shell .sx-row { display: flex; gap: 10px; align-items: flex-start;
  justify-content: space-between; padding: 10px 0;
  border-top: 1px solid var(--border); min-width: 0; }
body.shell .sx-row:first-child { border-top: 0; }
body.shell .sx-row .grow { min-width: 0; flex: 1; }
body.shell .sx-row .name { font-weight: 600; overflow-wrap: anywhere; }
body.shell .sx-row .meta { color: var(--muted); font-size: 12px;
  overflow-wrap: anywhere; }
body.shell .sx-amt { font-variant-numeric: tabular-nums; font-weight: 650;
  white-space: nowrap; text-align: right; }
body.shell .sx-amt.is-debit { color: var(--danger); }
body.shell .sx-empty { color: var(--muted); font-size: 14px; padding: 8px 0; }
body.shell .sx-actions { display: grid; gap: 10px; }
body.shell .sx-actions .btn { width: 100%; }
body.shell .sx-table { width: 100%; border-collapse: collapse; font-size: 13px;
  font-variant-numeric: tabular-nums; }
body.shell .sx-table th, body.shell .sx-table td { text-align: right;
  padding: 6px 4px; border-top: 1px solid var(--border); }
body.shell .sx-table th:first-child,
body.shell .sx-table td:first-child { text-align: left; }
body.shell .sx-scroll { overflow-x: auto; max-width: 100%; }
@media (min-width: 620px) {
  body.shell .sx-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  body.shell .sx-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
  body.shell .sx-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  body.shell .sx-net .sx-big { font-size: 34px; }
}
