/* Shared post-login shell: sidebar + topbar + design tokens, used by dashboard.html,
   label-process.html, history.html, and analytics.html. One file instead of repeating
   ~150 lines of tokens/layout CSS per page (same reasoning as vendoring Font Awesome
   once instead of per-page).

   Fonts load from Google Fonts (not self-hosted) — a deliberate, narrow exception to
   this project's usual "vendor it, no CDN" rule (see Font Awesome), same reasoning as
   the Google Identity Services script on /login: self-hosting three variable font
   families with many weights is disproportionate effort for a visual-match request,
   and Google Fonts serving CSS+WOFF2 carries no functional/security surface the way a
   3rd-party JS SDK would. */
@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700&display=swap');

:root {
  color-scheme: light dark;
  --font-body: 'Instrument Sans', system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-heading: 'Bricolage Grotesque', var(--font-body);
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  --page-bg: oklch(0.962 0.007 267);
  --panel-bg: #ffffff;
  --text: oklch(0.25 0.02 282);
  /* 0.53, not the 0.55 this started at: against --page-bg that was 4.37:1,
     just under WCAG AA's 4.5. Secondary copy is everywhere (table sub-lines,
     menu icons, hints, .view-tab labels), so the shortfall showed up on nearly
     every screen at once. 0.53 clears 4.5 against page-bg, panel-bg, accent-bg
     and border-soft alike. */
  --muted: oklch(0.53 0.02 282);
  --border: oklch(0.91 0.008 267);
  --border-soft: oklch(0.945 0.006 267);

  /*
    --accent is the accent as a SURFACE: a filled button, the active rail item,
    the avatar. White sits on it, so it has to stay dark in both themes.

    --accent-ink is the accent as TEXT: a sorted column header, "View all
    records", an active tab. That one has to inverse-track the theme — the same
    dark navy that reads well on a white card is 1.9:1 on a dark one, which is
    what made every sortable header and link in dark mode all but invisible.

    One token cannot do both: on a dark panel, ink needs L ≥ ~0.32 for 4.5:1,
    while white-on-accent needs L ≤ ~0.18. Hence the split rather than a tweak.
  */
  --accent: oklch(0.45 0.09 267);
  --accent-hover: oklch(0.37 0.07 272);
  --accent-bg: oklch(0.97 0.015 262);
  --accent-ink: var(--accent);
  --accent-ink-hover: var(--accent-hover);

  --cta-1: oklch(0.72 0.14 75);
  --cta-2: oklch(0.6 0.13 55);
  --brand-1: oklch(0.78 0.13 75);
  --brand-2: oklch(0.55 0.14 45);

  /* Same ink-vs-surface split as the accent above, but these three are ink in
     almost every use (the house pattern is `background: var(--X-bg); color:
     var(--X)`), so the solid token itself is the one that lightens in dark mode.
     --danger-solid is the exception kept for the few FILLED red buttons, which
     put white on the colour and so need it to stay dark in both themes. */
  --success: oklch(0.48 0.12 160);
  --success-dot: oklch(0.68 0.15 160);
  --success-bg: oklch(0.94 0.04 160);
  --danger: oklch(0.45 0.13 25);
  --danger-solid: oklch(0.45 0.13 25);
  --danger-bg: oklch(0.97 0.02 25);
  --danger-border: oklch(0.92 0.04 25);
  --warn: oklch(0.5 0.1 65);
  --warn-bg: oklch(0.975 0.02 75);
  --warn-border: oklch(0.93 0.04 75);

  --sidebar-1: oklch(0.22 0.035 282);
  --sidebar-2: oklch(0.19 0.03 287);
  --sidebar-text: oklch(0.74 0.02 272);
  --sidebar-text-active: #ffffff;
  --sidebar-border: oklch(0.3 0.03 282);
  --sidebar-active-bg: linear-gradient(135deg, oklch(0.38 0.06 272), oklch(0.32 0.05 277));

  /* Inter-state borders on the India choropleth (india-map.js). Tokens rather
     than a second `prefers-color-scheme` block down beside .in-state, so the
     light/dark/system resolution below is stated exactly once in this file. */
  --map-stroke: oklch(0.35 0.02 267 / 0.55);
  --map-stroke-strong: oklch(0.2 0.02 267 / 0.85);
  --map-hover-fill: oklch(0.62 0.16 152);

  --radius-lg: 15px;
  --radius-md: 10px;
  --radius-sm: 8px;
  --shadow-card: 0 1px 3px oklch(0.2 0.02 282 / 0.05);
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 22px;
}

/*
   Dark tokens, declared once and selected three ways — this is the pattern every
   dark block in the app now follows (ui-alerts.css, analytics-shared.css too).

     :root[data-theme="dark"]                       — chose Dark explicitly
     prefers-color-scheme + :not([data-theme=light]) — chose System, OS is dark
     (neither)                                       — chose Light, or System on a
                                                       light OS: the :root above

   theme.js stamps that attribute in <head> before first paint. The two dark
   selectors can't share one rule list (only one of them belongs inside the media
   query), so the token list is written out twice and the two copies must stay
   identical — a token added to only one of them silently works in "Dark" but not
   in "System on a dark OS", or the reverse.

   `color-scheme` rides along so form controls, scrollbars and the browser's own
   canvas follow the CHOICE, not the OS. Without it, forcing Light on a dark-mode
   laptop leaves native <select> popups and scrollbars black against the page. */
:root[data-theme="light"] { color-scheme: light; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --page-bg: oklch(0.19 0.015 267);
    --panel-bg: oklch(0.23 0.015 270);
    --text: oklch(0.92 0.005 267);
    --muted: oklch(0.68 0.01 267);
    --border: oklch(0.32 0.015 270);
    --border-soft: oklch(0.28 0.015 270);
    --accent-bg: oklch(0.27 0.03 262);
    --accent-ink: oklch(0.78 0.11 267);
    --accent-ink-hover: oklch(0.86 0.08 267);
    --success: oklch(0.74 0.14 160);
    --success-bg: oklch(0.28 0.05 160);
    --danger: oklch(0.72 0.15 25);
    --danger-bg: oklch(0.3 0.05 25);
    --danger-border: oklch(0.38 0.06 25);
    --warn: oklch(0.8 0.13 75);
    --warn-bg: oklch(0.3 0.04 75);
    --warn-border: oklch(0.38 0.05 75);
    --map-stroke: oklch(0.08 0.01 267 / 0.65);
    --map-stroke-strong: oklch(0.03 0.01 267 / 0.9);
    --map-hover-fill: oklch(0.72 0.16 152);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --page-bg: oklch(0.19 0.015 267);
  --panel-bg: oklch(0.23 0.015 270);
  --text: oklch(0.92 0.005 267);
  --muted: oklch(0.68 0.01 267);
  --border: oklch(0.32 0.015 270);
  --border-soft: oklch(0.28 0.015 270);
  --accent-bg: oklch(0.27 0.03 262);
  --accent-ink: oklch(0.78 0.11 267);
  --accent-ink-hover: oklch(0.86 0.08 267);
  --success: oklch(0.74 0.14 160);
  --success-bg: oklch(0.28 0.05 160);
  --danger: oklch(0.72 0.15 25);
  --danger-bg: oklch(0.3 0.05 25);
  --danger-border: oklch(0.38 0.06 25);
  --warn: oklch(0.8 0.13 75);
  --warn-bg: oklch(0.3 0.04 75);
  --warn-border: oklch(0.38 0.05 75);
  --map-stroke: oklch(0.08 0.01 267 / 0.65);
  --map-stroke-strong: oklch(0.03 0.01 267 / 0.9);
  --map-hover-fill: oklch(0.72 0.16 152);
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font-body);
  background: var(--page-bg);
  color: var(--text);
}
a { color: var(--accent-ink); text-decoration: none; }
a:hover { color: var(--accent-ink-hover); }
h1 { font-family: var(--font-heading); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; border: 2px solid transparent; background-clip: content-box; }
input, select, button { font-family: var(--font-body); }

.shell { display: flex; height: 100vh; overflow: hidden; }

/* ---------- sidebar ---------- */
.sidebar {
  width: 240px; flex-shrink: 0; background: linear-gradient(180deg, var(--sidebar-1), var(--sidebar-2));
  display: flex; flex-direction: column; color: var(--sidebar-text); overflow: hidden;
  transition: width 0.18s ease;
}
/* Collapsed state (desktop only — see the max-width:880px block below for the
   separate mobile drawer behavior, which ignores this entirely so a stale
   collapsed flag from a desktop session never leaves the mobile drawer stuck
   icon-only). The class lands on <html> (not <body>), stamped by a one-line
   addition to each page's own <head> auth-guard script, BEFORE first paint —
   that's what avoids a flash of a wide sidebar snapping narrow right after load;
   toggling it here on click (see shell.js initSidebarToggle) is what animates it
   back. */
@media (min-width: 881px) {
  html.sidebar-collapsed .sidebar { width: 72px; }
  html.sidebar-collapsed .sidebar-brand { padding: 22px 16px 20px; }
  html.sidebar-collapsed .sidebar-brand a { justify-content: center; }
  html.sidebar-collapsed .sidebar-logo { width: 32px; height: 32px; }
  html.sidebar-collapsed .sidebar-brand-text,
  html.sidebar-collapsed .nav-label,
  html.sidebar-collapsed .nav-badge,
  html.sidebar-collapsed .sidebar-mp { display: none; }
  html.sidebar-collapsed .sidebar-nav a { justify-content: center; padding: 10px 4px; }
}

/* Mobile off-canvas drawer — sidebar slides in over the content instead of
   pushing it, since there's no spare width to share below this point. Starts
   translated fully off-screen; shell.js's initSidebarToggle adds `sidebar-open`
   on <html> (deliberately not persisted — every page load is a real navigation,
   so starting closed each time is the expected mobile-nav behavior) to slide it
   in and show the backdrop. */
@media (max-width: 880px) {
  .sidebar {
    position: fixed; top: 0; left: 0; z-index: 200; height: 100vh; width: 240px;
    transform: translateX(-100%); transition: transform 0.22s ease;
  }
  html.sidebar-open .sidebar { transform: translateX(0); box-shadow: 0 0 48px oklch(0 0 0 / 0.4); }
  .sidebar-backdrop { display: none; }
  html.sidebar-open .sidebar-backdrop {
    display: block; position: fixed; inset: 0; z-index: 190; background: oklch(0 0 0 / 0.45);
  }
  .shell { position: relative; }
}
.sidebar-brand { display: flex; align-items: center; gap: 11px; padding: 22px 20px 20px; }
.sidebar-brand a { display: flex; align-items: center; gap: 11px; color: inherit; }
.sidebar-logo {
  width: 40px; height: 40px; object-fit: contain; flex-shrink: 0;
}
.sidebar-brand-name { display: block; font-weight: 700; font-size: 16.5px; letter-spacing: -0.2px; color: white; }
.sidebar-brand-sub { font-size: 10px; letter-spacing: 1.6px; color: oklch(0.68 0.06 257); font-weight: 600; }
.sidebar-nav { padding: 6px 12px 0; display: flex; flex-direction: column; gap: 2px; }
.sidebar-nav a {
  display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 10px;
  cursor: pointer; font-size: 14px; font-weight: 500; color: var(--sidebar-text);
  transition: background 0.15s; text-decoration: none;
}
.sidebar-nav a:hover { background: oklch(0.29 0.04 280); color: var(--sidebar-text-active); }
.sidebar-nav a.active {
  background: var(--sidebar-active-bg); color: var(--sidebar-text-active); font-weight: 600;
  box-shadow: 0 2px 8px oklch(0.2 0.03 282 / 0.5);
}
.sidebar-nav a .nav-icon { width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; }
.sidebar-nav a .nav-badge {
  margin-left: auto; font-size: 10.5px; font-weight: 700; background: oklch(0.35 0.05 272);
  color: oklch(0.85 0.05 262); padding: 2px 8px; border-radius: 20px;
}
.sidebar-mp { margin: 22px 12px 0; padding: 12px 12px 4px; border-top: 1px solid var(--sidebar-border); }
.sidebar-mp-title { font-size: 10px; letter-spacing: 1.5px; font-weight: 700; color: oklch(0.58 0.03 277); margin-bottom: 8px; }
.sidebar-mp-row { display: flex; align-items: center; gap: 9px; padding: 6px 2px; font-size: 13px; color: oklch(0.78 0.02 272); }
.sidebar-mp-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success-dot); flex-shrink: 0; }
.sidebar-mp-count { margin-left: auto; font-size: 11px; font-family: var(--font-mono); color: oklch(0.6 0.03 272); }
/* #apiKey is now a hidden input (see shell.js's SIDEBAR_HTML) — every page's
   script still reads/writes it by id for the dev-only X-Api-Key header, it's
   just no longer a visible sidebar-footer field, so no visual styling needed. */

/* ---------- topbar + main ---------- */
.shell-main { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
.topbar {
  flex-shrink: 0; display: flex; align-items: center; gap: 14px; padding: 12px 28px;
  background: var(--panel-bg); border-bottom: 1px solid var(--border);
}
.topbar-toggle {
  background: none; border: none; cursor: pointer; font-size: 15px; color: var(--muted);
  width: 34px; height: 34px; border-radius: 8px; display: flex; align-items: center;
  justify-content: center; flex-shrink: 0;
}
.topbar-toggle:hover { background: var(--page-bg); color: inherit; }
@media (max-width: 880px) {
  .topbar { padding: 10px 16px; gap: 10px; }
  /* Every shell page's own content starts with `<div style="padding:20px 28px
     32px">` (label-process.html is the one exception, with its own layout) —
     targeting that generically here, rather than editing all 8 files' inline
     styles, keeps the "change it once" goal intact for this too. !important
     because it's beating an inline style, not a specificity accident. */
  .shell-content > div:first-child { padding: 16px 16px 24px !important; }
}
@media (max-width: 560px) {
  .topbar-search { max-width: none; }
}
.topbar-search { flex: 1; max-width: 420px; position: relative; }
.topbar-search input {
  width: 100%; padding: 9px 14px 9px 36px; border-radius: 10px; border: 1px solid var(--border);
  font-size: 13px; background: var(--page-bg); color: inherit; outline-color: var(--accent);
}
.topbar-search .topbar-search-icon {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 13px; pointer-events: none;
}
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.topbar-label-process-btn {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; flex-shrink: 0;
  font-size: 13px; font-weight: 600; color: #fff; background: var(--accent);
  padding: 7px 14px; border-radius: 20px;
}
.topbar-label-process-btn:hover { background: var(--accent-hover); color: #fff; }
@media (max-width: 640px) { .topbar-label-process-btn span { display: none; } }
/* overflow-x explicit, not left to default — per the CSS overflow spec, when one
   axis is non-visible the other computes away from `visible` to `auto` too, so
   `overflow-y: auto` alone silently made this ALSO horizontally scrollable. That
   let any one wide element inside it (a data table with many columns, say) drag
   the WHOLE content area into horizontal scroll together — scrolling right to see
   a table's later columns also scrolled everything above/around it off-screen to
   the left, not just the table. Real pages should contain their own overflow in a
   dedicated wrapper (e.g. .table-scroll) instead of relying on this. */
.shell-content { flex: 1; overflow-y: auto; overflow-x: hidden; }

/* account pill (topbar), reused from account.js but restyled for the shell */
.account-pill {
  display: inline-flex; align-items: center; gap: 9px; white-space: nowrap; cursor: default;
  font-size: 13px; color: var(--text); padding: 4px 10px 4px 4px; border-radius: 20px; border: 1px solid var(--border);
}
.account-pill .avatar {
  width: 28px; height: 28px; border-radius: 50%; background: linear-gradient(135deg, oklch(0.65 0.11 257), oklch(0.5 0.1 277));
  color: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; flex-shrink: 0;
}
.account-pill .signout { color: var(--muted); font-size: 13px; line-height: 1; padding: 2px; }
.account-pill .signout:hover { color: var(--danger); }
.account-pill.signed-out { border-style: dashed; padding: 4px 12px; }
.account-pill.signed-out a { color: var(--accent-ink); font-weight: 600; }

/* account dropdown (My Profile / Sign out) */
#accountIndicator { position: relative; display: inline-block; }
button.account-pill {
  cursor: pointer; background: var(--panel-bg); font-family: inherit;
}
button.account-pill:hover { border-color: var(--accent); }
.account-pill .caret { color: var(--muted); font-size: 11px; transition: transform 0.15s; }
button.account-pill.open .caret { transform: rotate(180deg); }
.account-menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 180px; z-index: 60;
  background: var(--panel-bg); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.25); padding: 6px;
}
.account-menu a {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 8px;
  font-size: 13px; color: var(--text); text-decoration: none;
}
.account-menu a:hover { background: var(--page-bg); }
.account-menu a i { width: 16px; text-align: center; color: var(--muted); }
.account-menu a.danger, .account-menu a.danger i { color: var(--danger); }
.account-menu .sep { height: 1px; background: var(--border); margin: 5px 6px; }

/* ---------- admin submenu (account.js) ----------
   The admin sections, folded away inside the account menu. Ten entries would otherwise
   turn a four-item menu into a wall for the seller who is not an admin — and for the
   one who is, most visits are not admin visits. */
.account-sub-toggle {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px;
  border: none; border-radius: 8px; background: none; cursor: pointer;
  font: inherit; font-size: 13px; color: var(--text); text-align: left;
}
.account-sub-toggle:hover { background: var(--page-bg); }
.account-sub-toggle i { width: 16px; text-align: center; color: var(--muted); }
.account-sub-toggle .sub-caret { margin-left: auto; font-size: 10px; transition: transform .15s; }
.account-sub-toggle.open .sub-caret { transform: rotate(180deg); }
/* Indented and hung off a rule, so an open submenu reads as contained by the row above
   rather than as more of the same list. */
.account-sub { margin: 2px 0 4px 18px; padding-left: 8px; border-left: 2px solid var(--border); }
.account-sub[hidden] { display: none; }
.account-sub a { padding: 7px 10px; font-size: 12.5px; }

/* ---------- colour-theme control (theme.js) ---------- */
/* Sits in the topbar beside the account pill rather than inside its menu: it's a
   display setting, not an account one, and someone comparing the two themes wants
   it reachable in one click. Deliberately borrows .account-menu's popover
   vocabulary (same radius, padding, row height) so the two neighbours don't read
   as coming from different apps. */
/* Every rule here is written under #themeSwitch. That's not stylistic — an id
   puts these above anything a page's own stylesheet can say with element or
   class selectors, and label-process.html is a live example of a page that
   styles bare `button` and `button:hover` for its whole surface. Without the id
   the theme menu inherits that page's accent-blue fill and white label. */
#themeSwitch { position: relative; display: inline-block; flex-shrink: 0; }
#themeSwitch .theme-btn {
  background: none; border: 1px solid var(--border); cursor: pointer; font-size: 14px; color: var(--muted);
  width: 34px; height: 34px; padding: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
#themeSwitch .theme-btn:hover,
#themeSwitch .theme-btn.open { color: var(--accent-ink); border-color: var(--accent); background: var(--accent-bg); }
#themeSwitch .theme-menu {
  position: absolute; right: 0; top: calc(100% + 8px); min-width: 168px; z-index: 60;
  background: var(--panel-bg); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.25); padding: 6px;
}
#themeSwitch .theme-opt {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px; border: 0; border-radius: 8px;
  background: none; font: inherit; font-size: 13px; color: var(--text); text-align: left; cursor: pointer;
}
#themeSwitch .theme-opt:hover { background: var(--page-bg); color: var(--text); }
#themeSwitch .theme-opt > i:first-child { width: 16px; text-align: center; color: var(--muted); font-size: 13px; }
#themeSwitch .theme-opt span { flex: 1; }
/* The tick marks the active option; hidden (not removed) so the three rows keep
   equal width and the labels don't shuffle sideways as the selection moves. */
#themeSwitch .theme-opt .theme-tick { font-size: 11px; color: var(--accent-ink); visibility: hidden; }
#themeSwitch .theme-opt[aria-checked="true"],
#themeSwitch .theme-opt[aria-checked="true"]:hover { color: var(--accent-ink); font-weight: 600; }
#themeSwitch .theme-opt[aria-checked="true"] > i:first-child { color: var(--accent-ink); }
#themeSwitch .theme-opt[aria-checked="true"] .theme-tick { visibility: visible; }

/* ---------- shared card/table/badge vocabulary ---------- */
.sc-card { background: var(--panel-bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.sc-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.sc-table th {
  text-align: left; padding: 9px 12px; font-size: 11px; letter-spacing: 0.8px; font-weight: 600;
  color: var(--muted); border-bottom: 1px solid var(--border); background: var(--border-soft);
}
.sc-table td { padding: 11px 12px; border-bottom: 1px solid var(--border-soft); }
.sc-table tbody tr:hover td { background: var(--accent-bg); }
/* Shared across every .sc-table on every page (History, Admin, Products) — same
   ▲/▼ click-to-sort convention as label-process.html's Order Data table. */
.sc-table th.sortable-th { cursor: pointer; user-select: none; }
.sc-table th.sortable-th:hover { color: var(--accent-ink); }
.sc-table th.sortable-th.sorted { color: var(--accent-ink); }
.sc-table th .sort-indicator { font-size: 10px; margin-left: 3px; opacity: 0.8; }
.sc-pill {
  font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 12px; background: var(--border-soft);
  color: var(--text); text-transform: capitalize; display: inline-block;
}
.sc-status-done { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--success); }
.sc-status-done .sc-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--success-dot); }
.sc-btn {
  border: none; font-size: 13.5px; font-weight: 600; padding: 9px 16px; border-radius: 10px; cursor: pointer;
}
.sc-btn-cta {
  background: linear-gradient(135deg, var(--cta-1), var(--cta-2)); color: white;
  box-shadow: 0 2px 8px oklch(0.65 0.13 65 / 0.4); transition: filter 0.15s;
}
.sc-btn-cta:hover { filter: brightness(1.08); }
.sc-btn-secondary { border: 1px solid var(--border); background: var(--panel-bg); color: var(--text); }
.sc-btn-secondary:hover { background: var(--border-soft); }
.sc-btn-primary { border: none; background: var(--accent); color: white; }
.sc-btn-primary:hover { background: var(--accent-hover); }
.sc-mono { font-family: var(--font-mono); }

/* ---------- India state-wise choropleth (india-map.js) ---------- */
/* Shared by analytics.html and dashboard.html. Sequential single-hue ramp —
   set as `color` on each .in-state group and picked up via fill="currentColor"
   in the vendored SVG (assets/maps/india-states.svg) — never a rainbow, per
   the dataviz skill's sequential-encoding rule. */
.in-map-wrap { position: relative; max-width: 460px; margin: 0 auto; }
.in-map-wrap svg { width: 100%; height: auto; display: block; }
.in-state { cursor: pointer; color: var(--in-state-fill); transition: color 0.12s ease; }
/* A visible ink-toned border between states (not a pale surface-color gap —
   at this map's scale, especially the small northeastern cluster, a
   panel-bg stroke reads as "shape falling apart" rather than "distinct
   states"). Stronger still on hover so the highlighted state's outline
   reads clearly against its neighbors. */
.in-state path { stroke: var(--map-stroke); stroke-width: 1.1; stroke-linejoin: round; }

/* Hover recolours the state green and changes NOTHING else — no extra outline, no
   change to the resting border, no change to geometry or paint order.

   It works by swapping the fill colour only. india-map.js sets each state's own
   colour into --in-state-fill rather than straight onto `color`, so this rule can
   win on hover without !important — an inline style would otherwise always beat a
   class rule, which is why the colour is handed over through a custom property.

   Green on purpose, and deliberately NOT the --success token: the choropleth is a
   sequential blue ramp, so a green reads as "the one under the cursor" rather than
   as another value on the scale, and reusing a status colour for a pointer
   highlight would overload a reserved meaning. */
.in-state:hover, .in-state.in-state-hover, .in-state:focus-visible { color: var(--map-hover-fill); outline: none; }
.in-map-tooltip {
  position: fixed; transform: translate(-50%, calc(-100% - 8px));
  background: var(--text); color: var(--panel-bg); font-size: 11.5px; line-height: 1.5;
  padding: 7px 10px; border-radius: 8px; white-space: nowrap; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity 0.1s ease; z-index: 100;
  box-shadow: 0 8px 20px -6px rgba(0,0,0,0.35);
}
.in-map-tooltip.show { opacity: 1; visibility: visible; }
/* Body sans, not the mono figure font used elsewhere (.viz-tooltip etc.) —
   at this tooltip's small size JetBrains Mono's 0 and 8 are nearly
   identical (both closed, similarly rounded), which reads as a genuine
   ambiguous number rather than a style choice. Instrument Sans' 8 is
   clearly two-lobed against 0's single oval, and this value is a single
   floating figure (not a column), so there's no tabular-alignment need to
   trade away. */
.in-map-tooltip strong { font-family: var(--font-body); font-weight: 700; }
.in-map-legend { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 14px; font-size: 11px; color: var(--muted); }
.in-map-legend-ramp { display: inline-flex; border-radius: 4px; overflow: hidden; }
.in-map-legend-ramp span { width: 18px; height: 10px; }
.in-map-credit { text-align: center; font-size: 10px; color: var(--muted); margin-top: 8px; }
.in-map-credit a { color: var(--muted); text-decoration: underline; }
