/*
 * Every colour and radius the portal uses. The three stylesheets each had their
 * own :root and fifteen colours were written past them, so a palette change had
 * to be made in four places and agree in all of them.
 *
 * Load this first: the others only read.
 */
:root {
  /* The display face. Declared here rather than in shop/shop.css because the
     dashboard wants it too and never loads that sheet — read from there, it
     resolves to nothing and the text quietly falls back to the body face. */
  --display: 'Fraunces', ui-serif, Georgia, 'Times New Roman', serif;

  --bg: #fafafa;
  --bg2: #ffffff;
  --bg3: #f4f6f8;
  --bg4: #eaeef2;
  --topbar-bg: #1c1f23;  /* the dark strip — the one dark surface left */
  /* The strip's foot. A single flat fill reads as a block of colour at the 68px
     the bar now stands; two stops a few points apart read as a surface. Close
     enough to --topbar-bg that a screenshot diff barely moves — the point is the
     edge, not a visible gradient. */
  --topbar-bg2: #15181c;

  --border: #e0e0e0;
  --border2: #e8e8e8;

  /* Button labels run 13.5–15px/600, which doesn't qualify as large text, so
     the fill sits one step darker than the reference blue (#0091ff, only
     3.23:1 under white) to clear 4.5:1. The brighter blue survives as an
     accent — borders, icons, the hero gradient — never a labelled fill. */
  --base: #0074cc;
  /* unused today — reserved for a border, an icon or a gradient stop per
     the paragraph above, never a labelled fill. Leave it defined. */
  --base-l: #0091ff;
  --base-d: #005ca3;
  --base-bg: rgba(0,116,204,0.08);
  --section-bg: #f0f8ff;

  /* Channel triplets, because the sheets carry THIRTY distinct rgba() values
     — eight amber alphas alone. Naming each one is a token nobody remembers;
     composing them from a triplet means the light palette revalues six lines
     and every alpha follows. rgba(240,165,0,0.25) becomes
     rgba(var(--amber-rgb), 0.25), which is the same colour exactly — no
     colour-space conversion, so this stays a refactor. */
  --amber-rgb: 158,100,0;
  --teal-rgb: 13,130,95;
  --danger-rgb: 217,45,32;
  --on-dark-rgb: 255,255,255;
  --bg-rgb: 250,250,250;
  --shadow-rgb: 16,24,40;

  --amber: #9e6400;       /* darkened from #f0a500 — 4.7:1 on #fafafa */
  --amber-bg: rgba(var(--amber-rgb), 0.08);
  --amber-bg2: rgba(var(--amber-rgb), 0.15);
  --amber-l: #f0a500;
  /* THE WORDMARK'S GOLD, and deliberately not --amber-l even though it is the
     same value today. --amber is an ACCENT and body.shop legitimately repaints
     it (the storefront's accent is blue), so the wordmark riding on it turned
     "My" blue on the shop and gold on the dashboard — one brand, two colours,
     on the one element that appears on every page. Identity is not accent, so
     it gets its own token and body.shop does not override it. */
  --brand-mark: #f0a500;
  /* same problem as --teal-d: --amber on its own tint doesn't clear 4.5:1. */
  --amber-d: #7f5100;

  --teal: #0d825f;        /* darkened from #1abc8a — 4.6:1 on #fafafa */
  --teal-bg: rgba(var(--teal-rgb), 0.08);
  /* --teal on its own 8-12% tint only clears ~4.0-4.2:1, not 4.5 — a badge
     or alert reads its text against the tint, not the page ground behind it.
     Same relationship as --danger-d to --danger, one step darker. */
  --teal-d: #0a664b;

  /* Refusals and destructive actions. Hardcoded in four places before this. */
  --danger: #d92d20;
  /* also the error chip's text; was a pale salmon against a dark panel, now
     has to read dark against near-white, so it inverts instead of lightening */
  --danger-d: #a81c13;
  --danger-border: rgba(var(--danger-rgb), 0.25);
  --teal-border: rgba(var(--teal-rgb), 0.25);

  --text: #16191d;
  --text2: #5a626c;
  --text3: #8a929c;

  /* Labels ON a filled surface. These are not the page's text colour — the
     fills are dark enough now that white sits on every one of them
     (4.81 on --base, 4.91 on --amber, 4.83 on --danger), and that decision
     lives in one place rather than three. */
  --on-amber: #fff;
  --on-danger: #fff;
  --on-base: #fff;
  --on-teal: #fff;
  --on-dark: #fff;

  --shadow: 0 6px 20px rgba(var(--shadow-rgb), 0.08);
  /* The card resting/lifted pair. Here rather than in portal.css because a
     component sheet composing its own rgba() is a colour written outside the
     token layer, which is the thing this file exists to prevent. */
  --shadow-card: 0 4px 8px rgba(var(--shadow-rgb), 0.06);
  --shadow-card-hover: 0 6px 16px rgba(var(--shadow-rgb), 0.12);
  --scrim: rgba(var(--shadow-rgb), 0.55);
  /* The account and category menus hang over the page rather than sitting on
     it, so they carry more spread than --shadow-card. The nav has two states:
     a hairline while the page is at the top, a real shadow once it has
     scrolled under — that transition is the whole reason the row reads as
     fixed rather than as part of the page. */
  --shadow-menu: 0 12px 32px rgba(var(--shadow-rgb), 0.12);
  --shadow-nav: 0 1px 0 rgba(var(--shadow-rgb), 0.04);
  --shadow-nav-stuck: 0 6px 20px rgba(var(--shadow-rgb), 0.08);

  /* Everything above is a colour a probe can find written straight into a
     stylesheet. It can't tell rgba(var(--x-rgb), α) apart from a literal one —
     both just look like "rgba(" — so a one-off alpha still needs a name here
     even though nothing else on the page shares it. Same triplets, same
     alphas, just called by name at the one spot each is used. */
  --amber-10: rgba(var(--amber-rgb), 0.10);
  --amber-14: rgba(var(--amber-rgb), 0.14);
  --amber-20: rgba(var(--amber-rgb), 0.2);
  --amber-25: rgba(var(--amber-rgb), 0.25);

  --teal-12: rgba(var(--teal-rgb), 0.12);
  --teal-20: rgba(var(--teal-rgb), 0.2);
  --teal-30: rgba(var(--teal-rgb), 0.3);

  /* alphas of --danger, same family as --danger-10 below — not of --danger-d,
     despite what these were named before (that named the wrong base). */
  --danger-08: rgba(var(--danger-rgb), 0.08);
  --danger-12: rgba(var(--danger-rgb), 0.12);
  --danger-20: rgba(var(--danger-rgb), 0.2);
  --danger-30: rgba(var(--danger-rgb), 0.3);
  --danger-10: rgba(var(--danger-rgb), 0.10);

  /* on-dark-rgb stays white — it's only ever used on --topbar-bg, the one
     surface in this palette that's still dark. */
  --on-dark-10: rgba(var(--on-dark-rgb), 0.1);
  --on-dark-35: rgba(var(--on-dark-rgb), 0.35);
  /* The strip's own hairline, the account button's resting/hover fill and the
     two text weights inside it. All four were going to be written straight into
     chrome.css, which is the literal probe_portal_theme exists to catch. */
  --on-dark-06: rgba(var(--on-dark-rgb), 0.06);
  --on-dark-14: rgba(var(--on-dark-rgb), 0.14);
  --on-dark-55: rgba(var(--on-dark-rgb), 0.55);
  --on-dark-70: rgba(var(--on-dark-rgb), 0.7);

  --bg-88: rgba(var(--bg-rgb), 0.88);
  --bg-94: rgba(var(--bg-rgb), 0.94);
  --bg-96: rgba(var(--bg-rgb), 0.96);

  --shadow-35: rgba(var(--shadow-rgb), 0.35);
  --shadow-50: rgba(var(--shadow-rgb), 0.5);

  --r: 6px;
  --rl: 12px;

  /* How far down the viewport a sticky element has to start, so it comes to
     rest UNDER the chrome rather than beneath it. Zero here because .pt-nav is
     only pinned above the pills breakpoint; chrome.css raises this to the
     nav's measured height there, and that is the only place the breakpoint is
     written. Anything sticky on a portal page reads this rather than pinning
     itself to 0 — pinning to 0 is how the product page's buy panel came to
     rest behind the nav with its price line hidden. */
  --pt-sticky-top: 0px;
}

/*
 * THE STOREFRONT SKIN.
 *
 * Krishna asked for the product page to match the reference marketplace's look,
 * not only its layout. Scoped to body.shop — browse, product and cart — so the
 * dashboard, account and auth pages keep the palette above unchanged. Written
 * here rather than in shop.css because probe_portal_theme holds every other
 * sheet to naming no colour of its own, and a re-skin that hid literals in a
 * component sheet is exactly the half-inverted theme that probe exists to catch.
 *
 * The contrast reasoning in the :root block still applies and is honoured:
 * every value below that carries a label clears 4.5:1 against the ground it
 * sits on. The reference's own accent (#2563eb, 4.83:1 on white) would pass,
 * but the step darker is used for text-weight accent so it also clears on the
 * --bg3 tint, where the lighter one lands at 4.1:1.
 */
body.shop {
  /* Sans throughout. Fraunces is the portal's display face; the reference sets
     headings in the same grotesque as its body text. DM Sans is already
     self-hosted by fonts.css, so this costs no extra request. */
  --display: 'DM Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;

  --bg: #f5f7fa;
  --bg2: #ffffff;
  --bg3: #eef2f7;
  --bg4: #e3e8ef;
  --bg-rgb: 245,247,250;

  /* The shop header is the SAME dark strip the dashboard wears, so a buyer
     crossing between the storefront and their account does not see the chrome
     change colour under them. This block used to invert --topbar-bg and
     --on-dark to a white bar with dark text, following the reference design;
     that made the one element common to every page the one element that did
     not look common. The dark values now come through from :root, which is
     also where --on-dark-rgb, .pt-top .brand-tld and .pt-top .topbar-avatar
     already expect to be — each of those carries a light-ground variant
     specifically for this strip, and they were all being applied against
     white. */

  --border: #e3e8ef;
  --border2: #eef2f7;

  --text: #111827;   /* 16.9:1 on white */
  --text2: #4b5563;  /*  7.6:1 */
  --text3: #6b7280;  /*  5.2:1 */

  /* The primary fill is near-black, as the reference's "Buy Product Now" is.
     White on it is 16.9:1. */
  --base: #111827;
  --base-l: #1f2937;
  --base-d: #000000;
  --base-bg: rgba(17,24,39,0.06);
  --section-bg: #f5f7fa;

  /* --amber is the storefront's accent: the price, the order total, the active
     tab's underline and the selected licence card all read it. Re-pointed at
     the reference's blue rather than renamed. 7.0:1 on white. */
  --amber-rgb: 29,78,216;
  --amber: #1d4ed8;
  --amber-l: #2563eb;
  --amber-d: #1e40af;

  /* EVERY DERIVED TOKEN HAS TO BE RE-DECLARED HERE, and this is not tidiness.
     A token like --on-dark-70, declared once as rgba(var(--on-dark-rgb), 0.7)
     on :root, is substituted AT :ROOT using :root's triplet; what inherits down
     is the finished colour string, not the recipe. Overriding the triplet in
     this block therefore reaches nothing that was composed above it.
     Re-declaring each derived token inside this block makes it compose again
     here, against the triplets above.
     Found the hard way: flipping --on-dark-rgb alone left the header's language
     switcher and "Create account" as white-on-white — present, focusable, and
     invisible, which is worse than missing. */
  --on-dark-06: rgba(var(--on-dark-rgb), 0.06);
  --on-dark-10: rgba(var(--on-dark-rgb), 0.1);
  --on-dark-14: rgba(var(--on-dark-rgb), 0.14);
  --on-dark-35: rgba(var(--on-dark-rgb), 0.35);
  --on-dark-55: rgba(var(--on-dark-rgb), 0.55);
  --on-dark-70: rgba(var(--on-dark-rgb), 0.7);

  --amber-bg:  rgba(var(--amber-rgb), 0.08);
  --amber-bg2: rgba(var(--amber-rgb), 0.15);
  --amber-10:  rgba(var(--amber-rgb), 0.10);
  --amber-14:  rgba(var(--amber-rgb), 0.14);
  --amber-20:  rgba(var(--amber-rgb), 0.2);
  --amber-25:  rgba(var(--amber-rgb), 0.25);

  --bg-88: rgba(var(--bg-rgb), 0.88);
  --bg-94: rgba(var(--bg-rgb), 0.94);
  --bg-96: rgba(var(--bg-rgb), 0.96);

  --r: 8px;
  --rl: 12px;
}
