/* Runix skin for the Router console.
 *
 * New API v1 is shadcn/ui + Tailwind: every colour comes from a small set of
 * design tokens (--primary, --background, --card, --border, --ring, ...).
 * Repainting those tokens restyles the whole UI at once, so the console stays
 * consistent by construction instead of chasing individual components.
 * Injected by nginx, so container upgrades keep the skin.
 *
 * The structure follows Cloudscape, AWS's console design system, because a
 * control plane should read like one: white page AND white containers,
 * separation carried by a 1px border plus radius rather than by tinted
 * backgrounds, 14px/20px body text, headings at weight 700 with tightening
 * negative tracking, and a 4px spacing grid whose container step is 20px.
 *
 * What is deliberately NOT taken from Cloudscape:
 *   - its accent #006ce0. One accent does link, primary button, focus ring,
 *     selected state and active nav there, and that idea is kept -- but the
 *     hue stays Runix indigo #4a5bd6 so the console and runixcloud.io read as
 *     one product. Cloudscape's contribution here is rhythm and density, not
 *     brand colour. Its hover-darkens idiom IS adopted: #4a5bd6 -> #3846b8.
 *   - its Open Sans. The package does not ship the webfont, and this site
 *     already self-hosts Inter. Borrowing the scale without the face is the
 *     cheaper, more consistent trade.
 */

/* ---------- design tokens: repaint shadcn in Runix + Cloudscape ---------- */
:root, .dark, body, [data-theme-font] {
  --background: #ffffff !important;
  --foreground: #0d1117 !important;
  /* Containers are white too. Cloudscape never separates a card from the page
   * with a grey fill -- that was the retired pre-3.0 "classic" look, and using
   * it is the single most common way a restyle fails to read as current. */
  --card: #ffffff !important;
  --card-foreground: #0d1117 !important;
  --popover: #ffffff !important;
  --popover-foreground: #0d1117 !important;
  --primary: #4a5bd6 !important;
  --primary-foreground: #ffffff !important;
  --secondary: #f6f6f9 !important;
  --secondary-foreground: #0d1117 !important;
  --muted: #f6f6f9 !important;
  --muted-foreground: #656871 !important;
  --accent: #eef1fb !important;
  --accent-foreground: #0d1117 !important;
  /* The border does the work the background used to. Cloudscape's divider is
   * #c6c6cd -- considerably more present than the 8%-black hairline this file
   * used to carry, and that visibility is the point. */
  --border: #c6c6cd !important;
  --input: #8c8c94 !important;
  --ring: #4a5bd6 !important;
  --destructive: #db0000 !important;
  --destructive-foreground: #ffffff !important;
  --chart-1: #4a5bd6 !important;
  --chart-2: #0b96b8 !important;
  --chart-3: #00802f !important;
  --chart-4: #855900 !important;
  --chart-5: #db0000 !important;
  --sidebar: #ffffff !important;
  --sidebar-foreground: #424650 !important;
  --sidebar-primary: #4a5bd6 !important;
  --sidebar-primary-foreground: #ffffff !important;
  --sidebar-accent: #eef1fb !important;
  --sidebar-accent-foreground: #0d1117 !important;
  --sidebar-border: #ebebf0 !important;
  --sidebar-ring: #4a5bd6 !important;
  --radius: 8px;
  color-scheme: light !important;

  /* Height of the Runix bar. Everything that has to sit below it derives from
   * this one number -- see the layout block. */
  --rx-topbar-h: 32px;
}

html, body { background-color: #ffffff !important; color: #0d1117 !important; }
body {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", sans-serif !important;
  /* Cloudscape body: 14px/20px, weight 400. Console density, not marketing. */
  font-size: 14px !important;
  line-height: 20px !important;
}

/* Headings: all weight 700, tracking tightening as size grows. This is the
 * cheapest, highest-signal Cloudscape tell. */
h1, .text-2xl { font-size: 24px !important; line-height: 30px !important; font-weight: 700 !important; letter-spacing: -0.02em !important; }
h2, .text-xl  { font-size: 20px !important; line-height: 24px !important; font-weight: 700 !important; letter-spacing: -0.015em !important; }
h3, .text-lg  { font-size: 18px !important; line-height: 22px !important; font-weight: 700 !important; letter-spacing: -0.01em !important; }
h4            { font-size: 16px !important; line-height: 20px !important; font-weight: 700 !important; letter-spacing: -0.005em !important; }

/* Containers: 1px border + radius + a shadow soft enough to read as depth
 * rather than as decoration, and 20px of padding -- Cloudscape's odd but
 * distinctive first-class spacing step. */
[data-slot="card"], .rounded-lg.border, [class*="rounded-xl"][class*="border"] {
  border-color: #c6c6cd !important;
  box-shadow: 0 1px 2px rgba(15, 20, 26, 0.06), 0 4px 12px rgba(15, 20, 26, 0.04) !important;
}
[data-slot="card-content"], [data-slot="card-header"] { padding: 20px !important; }

/* Tables: header row is white like everything else, rows separated by the
 * secondary divider, and the shaded cell is the only tint in the system. */
thead th { background: #ffffff !important; border-bottom: 1px solid #c6c6cd !important; font-weight: 700 !important; }
tbody tr { border-bottom: 1px solid #ebebf0 !important; }
tbody tr:hover { background: #f6f6f9 !important; }

/* One accent, everywhere it belongs, darkening on hover. */
a:not(.rx-back):not([class*="button"]) { color: #4a5bd6; }
a:not(.rx-back):not([class*="button"]):hover { color: #3846b8; }
:focus-visible { outline: 2px solid #4a5bd6 !important; outline-offset: 2px !important; }

/* Status colours are carried by the --destructive token above and by whatever
 * the app maps success/warning to; there is nothing to restate here.
 *
 * There used to be a block matching [class*="destructive"], [class*="success"]
 * and [class*="warning"]. It looked harmless and was not: an attribute
 * substring match also catches conditional Tailwind classes like
 * hover:text-destructive and focus-visible:ring-destructive, so 22 elements --
 * the sidebar toggle, the search button, several icons -- were painted error
 * red permanently instead of on hover. The literal selectors it was really
 * aiming at (.text-red-500 and friends) matched nothing at all in this build,
 * so the whole block was pure cost. */

/* The primary call-to-action keeps the site's gradient; everything else uses
 * the flat indigo above so there is exactly one loud control per view. */
button[type="submit"], a[href="/sign-in"] {
  background-image: linear-gradient(100deg, #4a5bd6, #0b96b8) !important;
  color: #ffffff !important;
  border: none !important;
}
button[type="submit"]:hover { filter: brightness(1.04); }

/* App header: muted items, dark on hover -- the console's own chrome should
 * recede behind the content. */
header a { color: #656871 !important; }
header a:hover { color: #0d1117 !important; }
header a:has(img), header a:has(svg) { color: #0d1117 !important; }

/* Nothing a customer has to read should sit below 12px, which is Cloudscape's
 * small step and the floor the marketing site already holds itself to. Three
 * places in New API drop to 11: the sidebar group headings (Chat / General /
 * Personal) and the stat labels on the overview. Raised, not restyled -- the
 * headings live in an h-8 row with room to spare.
 *
 * Found by measuring computed styles across every console screen; the decorative
 * ghosted <pre> behind the onboarding card is deliberately left alone, since it
 * sits at 5% alpha under a mask gradient and is not meant to be read. */
[data-slot="sidebar-group-label"] { font-size: 12px !important; }
.text-\[11px\], .text-\[10px\] { font-size: 12px !important; }
[data-slot="avatar-fallback"] { font-size: 12px !important; }

/* Tailwind opacity modifiers were quietly undoing the token work. The muted
 * token is #656871, which is 5.3:1 on white and passes -- but the app writes
 * `text-muted-foreground/60`, and six tenths of it composites to 2.49:1. The
 * sidebar group headings do the same thing at /70 and land on 2.99:1.
 * Measured, not inferred: the computed value comes back as
 * oklab(0.517776 ... / 0.6).
 *
 * Darkening the token instead would need it near #1b1b1b to survive a 60%
 * multiply, which is body-text dark and would stop it reading as muted at all.
 * Dropping the alpha on these specific utilities keeps the intended hierarchy
 * and passes AA.
 *
 * `~=` matches a whole whitespace-separated class token, so
 * `hover:text-muted-foreground/60` is NOT caught -- the earlier
 * [class*="destructive"] rule made exactly that mistake and froze 22 hover
 * states into permanent error red. */
[class~="text-muted-foreground/50"],
[class~="text-muted-foreground/60"],
[class~="text-muted-foreground/70"],
[class~="text-muted-foreground/80"] { color: #656871 !important; }
[data-slot="sidebar-group-label"] { color: #424650 !important; }

/* ---------- the Runix bar, and the layout it has to live inside ----------
 *
 * Three things stack at the top and all three have to agree, which the
 * previous version got wrong:
 *
 *   1. this bar          fixed,  top: 0,                       height 32px
 *   2. New API's header  sticky, top: 0 by default             height 48px
 *   3. the sidebar       fixed,  top: var(--app-header-height)  (48px)
 *
 * Adding body{padding-top} only moved (2)'s initial position: on scroll it
 * still stuck to viewport top and slid under this bar, and (3) never moved at
 * all, so the sidebar overlapped the header by the height of the bar. Each of
 * the three is offset explicitly instead, all derived from --rx-topbar-h.
 *
 * The sidebar is matched on the literal Tailwind arbitrary-value class rather
 * than on a component class, because that string is what the markup actually
 * carries and it survives class-name churn in the bundle.
 */
/* z-index 45, and that number is load-bearing.
 *
 * Every floating layer this build has -- sheet-content, sheet-overlay,
 * dialog-content, dialog-overlay, alert-dialog-* -- is `fixed ... z-50`.
 * The bar used to be z-60, which put it above all of them, and because the
 * right-hand drawer carries `inset-y-0` (top:0;bottom:0) it starts at viewport
 * y=0 rather than below the bar. So the bar painted over the drawer's first
 * 32px: in the create-API-key drawer that is exactly the title and its
 * subtitle, which is what the reported clipping was.
 *
 * 45 sits in the empty band between New API's sticky header (z-40, already
 * offset below the bar by the layout block above) and every overlay (z-50).
 * One number fixes sheets, dialogs and alert dialogs together, and any future
 * z-50 layer inherits the fix.
 *
 * Deliberately NOT the reverse fix (pushing overlays to z-70): that needs a
 * separate !important rule per slot fighting Tailwind's own z-50, and silently
 * misses whatever the next upgrade adds.
 *
 * Nothing legitimately between 40 and 50 was displaced -- checked the shipped
 * bundle: the only higher values are z-100 (dropdown/combobox popups, which
 * must stay above the bar and do) and z-0/1/10/20/30.
 *
 * A modal overlay dimming the bar along with the page is the correct reading:
 * while a drawer is open the bar is not interactive anyway. */
#runix-topbar {
  position: fixed; top: 0; left: 0; right: 0; height: var(--rx-topbar-h); z-index: 45;
  display: flex; align-items: center;
  padding: 0 16px;
  background: #ffffff;
  border-bottom: 1px solid #ebebf0;
  font-family: Inter, -apple-system, "PingFang SC", sans-serif;
  font-size: 13px;
}
#runix-topbar .rx-back {
  display: inline-flex; align-items: center; gap: 8px;
  color: #0d1117 !important; text-decoration: none; font-weight: 700; letter-spacing: -0.01em;
}
#runix-topbar .rx-back:hover { color: #3846b8 !important; }
#runix-topbar .rx-back svg { display: block; }
/* 2.06:1 as #b4b4bb. Decorative, but it is still a rendered glyph, so it goes
 * to the same secondary text colour everything else muted uses (5.3:1). */
#runix-topbar .rx-sep { color: #656871; font-weight: 400; }
#runix-topbar .rx-prod {
  background: linear-gradient(100deg, #4a5bd6, #0b96b8);
  -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 700;
}

.rx-has-topbar body { padding-top: var(--rx-topbar-h) !important; }
/* (2) stick below the bar instead of under it */
.rx-has-topbar header.sticky, .rx-has-topbar header.fixed { top: var(--rx-topbar-h) !important; }
/* (3) the fixed sidebar starts below bar + header, and loses that much height */
.rx-has-topbar [class*="top-[var(--app-header-height"] {
  top: calc(var(--app-header-height, 3rem) + var(--rx-topbar-h)) !important;
}
.rx-has-topbar [class*="h-[calc(100svh-var(--app-header-height"] {
  height: calc(100svh - var(--app-header-height, 3rem) - var(--rx-topbar-h)) !important;
}

/* Left over from when nav items were hidden client-side. Items Runix does not
 * want are removed server-side now via HeaderNavModules / SidebarModulesAdmin,
 * so nothing paints and then vanishes; this stays only as a safety net. */
.rx-nav-hidden { display: none !important; }
