/* Brand palette + global cascade for the Rask showcase. These rules target :root,
   global Bootstrap classes, shell tags (html/body), and markup rendered by other
   components (Raw-injected syntax-highlight spans), so they are deliberately NOT scoped.
   Plain global stylesheet served from wwwroot and linked from App.cs's <Head>. */

:root {
    /* The violet dark-first palette lives in Styles/app.css now, compiled into this project's own
       stylesheet — it used to come from Rask.Bootstrap's tokens.css, which is gone. This block keeps
       what is specific to the showcase: the type system, the fixed nav height, thin --rask-* aliases so
       the existing var(--rask-*) references across this file + GuideChrome.css keep resolving, and the
       two fixed-dark code-surface tokens (code blocks stay dark in both themes). */
    --rask-accent: var(--accent);
    --rask-accent-strong: var(--accent-2);
    --rask-accent-soft: color-mix(in srgb, var(--accent) 15%, transparent);
    --rask-gradient: linear-gradient(135deg, var(--accent), var(--accent-2));

    --rask-ink: #14101f; /* deep violet-black: code panes — always dark, both themes */
    --rask-ink-2: #211b30; /* one step lifted from ink */
    --rask-mist: var(--panel-2); /* faint lifted surface for boxes (Chapters TOC, etc.) */
    --rask-line: var(--line); /* hairline */
    --rask-body: var(--ink); /* body text */

    /* Type system: Space Grotesk (display) / Inter (body) / JetBrains Mono (code). Routed through
       Bootstrap's own font vars so every Bs component picks them up, plus --font-* for direct use. */
    --font-display: "Space Grotesk", "Inter", system-ui, sans-serif;
    --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

    --nav-h: 56px;
}

body {
    font-family: var(--font-body);
    /* Inter stylistic sets: single-storey a (cv11), open digits — quiet, technical legibility. */
    font-feature-settings: "cv11", "ss01";
    color: var(--rask-body);
    letter-spacing: -0.004em;
}

/* Headings carry the display face — tighter tracking, a touch more weight than Bootstrap's default. */
h1, h2, h3, h4, h5, h6,
.app-brand {
    font-family: var(--font-display);
    letter-spacing: -0.022em;
}

.display-5 {
    font-weight: 700;
}

/* THERE IS NO GLOBAL `a { color }` RULE, and that is deliberate.

   There was one, and it silently defeated every Tailwind text-colour utility on every link in the
   site. The landing page's primary call to action reads `bg-ui-ink text-ui-bg` and rendered as brand
   violet on near-black — a contrast ratio of 2.12:1, found by Lighthouse rather than by eye. The class
   was there, the token was right, and the rule never applied.

   Neither obvious repair works. Unlayered, a tag rule beats every layered utility outright. Moved into
   `@layer base` here, it becomes a NEW layer after everything the kit and app sheets declared, because
   layer names do not merge across separate <link> stylesheets. Even written into the app's own Tailwind
   entry — same sheet, base emitted before utilities — the browser still ranked it above them.

   So the rule is gone. In a utility-first codebase a tag is the wrong place to put a colour: chrome
   links (nav, cards, buttons) carry their own utilities, and prose links are styled by their CONTAINER
   below, which is a class and therefore something a utility can be reasoned about against. */

code, pre, .font-monospace {
    font-family: var(--font-mono);
}

:not(pre) > code {
    background: var(--rask-accent-soft);
    color: var(--rask-accent);
    padding: 0.08rem 0.32rem;
    border-radius: 4px;
    font-size: 0.86em;
}

pre {
    margin: 0;
}

.rask-badge {
    background: var(--rask-accent-soft);
    color: var(--rask-accent);
}

.text-accent {
    color: var(--rask-accent) !important;
}

/* Shell-tag global rules. */
html {
    -webkit-text-size-adjust: 100%;
}

body {
    -webkit-tap-highlight-color: transparent;
    overscroll-behavior-y: none;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
}

/* The page ground — the deep violet-black (or light tint in light mode) from the shared tokens.
   !important because Bootstrap's own .bg-body-tertiary is an !important utility (keyed off
   --bs-tertiary-bg-rgb), which would otherwise win over a plain selector. */
body.bg-body-tertiary {
    background-color: var(--ground) !important;
}

button, a, [role="button"] {
    touch-action: manipulation;
}

/* From ShowcaseLayout: lock body scroll while the mobile nav drawer (the responsive offcanvas) is
   shown — :has() reaches up from the backdrop the open drawer renders; body is a shell tag, so this
   global stylesheet (it could never be component-scoped). */
@media (max-width: 767.98px) {
    body:has(.nav-backdrop) {
        overflow: hidden;
        height: 100vh;
    }

    /* Keep the top navbar a single line on phones: never wrap, and drop the decorative brand badges
       ("showcase" + version pill) that pushed the brand + GitHub button onto a second row. */
    .app-navbar {
        flex-wrap: nowrap;
    }

    .app-navbar .app-brand .rask-badge {
        display: none;
    }
}

/* From CodeSample: ColorCode emits <span class="keyword|string|comment|…"> token markup
   injected through Raw(), so those spans carry no scope attribute. Anchored under
   .sample-code so the generic class names don't leak page-wide. Dark palette tuned to
   the #1f1d2b background / #e7e3ff base text. */
:is(.sample-code, .markdown-body pre) .keyword,
:is(.sample-code, .markdown-body pre) .preprocessorKeyword {
    color: #c792ea;
}

:is(.sample-code, .markdown-body pre) .string,
:is(.sample-code, .markdown-body pre) .stringCSharpVerbatim {
    color: #c3e88d;
}

:is(.sample-code, .markdown-body pre) .stringEscape {
    color: #89ddff;
}

:is(.sample-code, .markdown-body pre) .comment {
    color: #6b6786;
    font-style: italic;
}

:is(.sample-code, .markdown-body pre) .xmlDocComment {
    color: #6b6786;
    font-style: italic;
}

:is(.sample-code, .markdown-body pre) .xmlDocTag {
    color: #8b87a8;
}

:is(.sample-code, .markdown-body pre) .number {
    color: #f78c6c;
}

:is(.sample-code, .markdown-body pre) .className {
    color: #82aaff;
}

:is(.sample-code, .markdown-body pre) .plainText {
    color: #e7e3ff;
}

/* CSS-language tokens (ColorCode's CSS lexer): selectors, property names and values. The
   JS lexer reuses the shared keyword/string/comment/number classes above. */
:is(.sample-code, .markdown-body pre) .cssSelector {
    color: #82aaff;
}

:is(.sample-code, .markdown-body pre) .cssPropertyName {
    color: #89ddff;
}

:is(.sample-code, .markdown-body pre) .cssPropertyValue {
    color: #c3e88d;
}

/* CodeSample: the source pane and the live result stack vertically (code first); a hairline
   divides them now that they are no longer side-by-side columns. */
.sample-result-col {
    border-top: 1px solid rgba(124, 58, 237, 0.15);
}

/* ShowcaseLayout: the app shell (navbar + responsive-offcanvas sidebar + main). These rules are
   GLOBAL rather than a scoped {Component}.css because the sidebar is built from several nested
   Rask.Bootstrap components (BsNavbar / BsOffcanvas / BsCollapse / BsNav / BsNavItem → NavLink), so
   the elements they render (e.g. .offcanvas-body, the .side-nav-link anchors) sit several component
   levels below ShowcaseLayout and never carry its scope id. Same rationale as the .sample-code rules
   above — markup another component renders can't be component-scoped. The .side-nav* / .nav-group* /
   .app-* class names are specific enough not to leak. */

/* Sticky top bar — a fixed violet-black glass (kept dark in both themes so the BsNavbar's Theme:Dark
   light text stays readable), matching the marketing site's dark topbar. */
.app-navbar {
    background: rgba(20, 16, 31, 0.82) !important;
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    padding-top: calc(0.5rem + env(safe-area-inset-top));
    z-index: 1046;
}

/* Hamburger toggle — a transparent icon button shown only below md (the d-md-none utility hides it
   at >=md, where the sidebar is static). */
.hamburger-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    border: 0;
    background: transparent;
    color: #fff;
    border-radius: 0.5rem;
    margin-right: 0.25rem;
    padding: 0;
}

.hamburger-btn:hover,
.hamburger-btn:focus {
    background: rgba(255, 255, 255, 0.08);
    outline: none;
}

.hamburger-btn .bi {
    font-size: 1.4rem;
    line-height: 1;
}

/* The shell row: sidebar + main, laid out with the Display.Flex utility on the wrapper. */
.app-shell {
    align-items: flex-start;
}

/* The sidebar is a responsive offcanvas (offcanvas-md): a slide-in drawer below md, a fixed-width
   static column at >=md. */
/* The body is a non-scrolling flex column: a pinned filter header over a single scrolling list. The
   filter is a real flex header (not position:sticky) because a sticky child of a flex container does
   not stick in Safari — it would scroll away with the list. This is bulletproof across browsers. */
/* The sidebar body is a non-scrolling flex column: the filter is a pinned header and the LIST inside
   scrolls. BsOffcanvas used to supply this container as .offcanvas-body; the container is now the
   <aside> itself, and loading after the utilities is what lets overflow:hidden beat its overflow-y-auto. */
.side-nav {
    /* NO display here. This file loads after the utilities, so `display: flex` would beat the
       `hidden` utility and the mobile drawer could never close. Tailwind owns display (hidden /
       md:flex on the element); this rule owns only the column layout the pinned filter needs. */
    flex-direction: column;
    padding: 1rem 0.75rem;
    overflow: hidden;
}

/* Pinned filter header — a fixed-height flex item over the scrolling list, with a hairline divider so
   list rows read as scrolling cleanly beneath it rather than clipping against a hard edge. */
.side-nav-search {
    flex: 0 0 auto;
    padding-bottom: 0.5rem;
    margin-bottom: 0.25rem;
    background: var(--ground);
    border-bottom: 1px solid var(--rask-line);
}

/* The single scrolling region: the nav list scrolls here (never the body), so the filter stays put. */
.side-nav-scroll {
    flex: 1 1 auto;
    min-height: 0; /* let the list scroll inside the flex column instead of stretching it */
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.side-nav-filter {
    border-radius: 0.5rem;
}

.side-nav-section {
    font-family: var(--font-mono);
    text-transform: uppercase;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    color: var(--rask-accent);
    padding: 0.75rem 0.5rem 0.25rem;
    margin-top: 0.5rem;
    border-top: 1px solid var(--rask-line);
}

.side-nav-section:first-of-type {
    margin-top: 0;
    border-top: 0;
}

/* Group toggle: a full-width, borderless button revealing/hiding its items via BsCollapse. */

/* The sidebar's links, groups and active state are daisyUI's `menu` now — see ShowcaseLayout, which
   renders a real <ul>/<li> tree and marks the current entry with `menu-active`. The rules that used to
   live here are gone rather than overridden: kept alongside daisyUI's they would have doubled its
   padding and its hover, which is worse than either on its own. The .side-nav-link and .nav-group-*
   names survive on the elements because the tests name them, not because anything styles them. */

.side-nav-empty {
    padding: 1rem 0.5rem;
}

/* Main content column. */
.page-main {
    min-width: 0; /* let long code blocks scroll instead of stretching the flex item */
    padding-bottom: calc(2rem + env(safe-area-inset-bottom));
}

.page-main-inner {
    max-width: 1280px;
}

/* Desktop: pin the static sidebar under the navbar and let only its list scroll, so a long list
   never stretches the page or hides its bottom entries below the fold. */
@media (min-width: 768px) {
    .side-nav {
        flex: 0 0 280px;
        width: 280px;
        position: sticky;
        top: var(--nav-h);
        align-self: flex-start;
    }

    /* Cap the body to the viewport minus the navbar so the inner .side-nav-scroll (not the page) is the
       bounded scroll region — a long, fully-expanded list scrolls inside itself, filter pinned above. */
    .side-nav.offcanvas-md .offcanvas-body {
        max-height: calc(100vh - var(--nav-h));
    }
}

/* Mobile drawer: account for the fixed navbar and notch insets when the offcanvas slides in. */
@media (max-width: 767.98px) {
    .side-nav {
        padding-top: calc(var(--nav-h) + env(safe-area-inset-top));
    }
}

/* GuidePage: the Markdig-rendered guide HTML (docs/*.md) is injected verbatim via Raw(), so it carries
   no scope id — these rules live here (global) and are anchored under .markdown-body so they never leak
   into the rest of the app. Readable defaults; the broader visual pass refines them. */
.markdown-body {
    max-width: 52rem;
    line-height: 1.7;
    color: var(--ink);
}

/* Clear the sticky navbar when an in-page anchor (Chapters TOC / on-this-page rail) jumps to a heading. */
.markdown-body :is(h1, h2, h3, h4) {
    scroll-margin-top: calc(var(--nav-h) + 1.25rem);
}

.markdown-body h1 {
    font-weight: 700;
    margin-bottom: 1rem;
}

.markdown-body h2 {
    font-weight: 700;
    font-size: 1.5rem;
    margin-top: 2.5rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.3rem;
    border-bottom: 1px solid var(--line);
}

.markdown-body h3 {
    font-weight: 600;
    font-size: 1.2rem;
    margin-top: 1.75rem;
    margin-bottom: 0.5rem;
}

.markdown-body p,
.markdown-body ul,
.markdown-body ol {
    margin-bottom: 1rem;
}

.markdown-body li {
    margin-bottom: 0.25rem;
}

/* Underlined at rest, not on hover. A link inside a paragraph that is distinguished only by colour
   fails WCAG 1.4.1 unless it also clears 3:1 against the surrounding text, and accent-on-ink is
   2.39:1 here — so the underline is what makes these links links, for a reader who cannot separate
   the two colours and for one who never hovers because they are using a touch screen. */
.markdown-body a {
    color: var(--rask-accent);
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.markdown-body a:hover {
    text-decoration: underline;
}

.markdown-body pre {
    background: var(--rask-ink);
    color: #e7e3ff;
    padding: 1rem 1.2rem;
    border-radius: 0.7rem;
    overflow-x: auto;
    margin-bottom: 1.25rem;
    font-size: 0.85rem;
    line-height: 1.6;
    border: 1px solid rgba(124, 58, 237, 0.18);
}

.markdown-body pre code {
    background: transparent;
    color: inherit;
    padding: 0;
    font-size: inherit;
}

.markdown-body :not(pre) > code {
    background: var(--rask-accent-soft);
    color: var(--rask-accent);
    padding: 0.08rem 0.34rem;
    border-radius: 4px;
    font-size: 0.86em;
}

.markdown-body blockquote {
    border-left: 4px solid var(--rask-accent);
    background: var(--rask-accent-soft);
    margin: 0 0 1.25rem;
    padding: 0.6rem 1rem;
    border-radius: 0 0.4rem 0.4rem 0;
}

.markdown-body blockquote > :last-child {
    margin-bottom: 0;
}

.markdown-body table {
    width: 100%;
    margin-bottom: 1.25rem;
    border-collapse: collapse;
    font-size: 0.92rem;
}

.markdown-body th,
.markdown-body td {
    border: 1px solid var(--line);
    padding: 0.5rem 0.75rem;
    text-align: left;
}

.markdown-body th {
    background: var(--panel-2);
    font-weight: 600;
}

.markdown-body img {
    max-width: 100%;
}

.markdown-body hr {
    margin: 2rem 0;
    border: 0;
    border-top: 1px solid var(--line);
}

/* SeeAlso: small accent pills linking a demo page to its guide(s). A dedicated class (not Bootstrap's
   .badge) so it never collides with demo markup that the page itself renders. */
.see-also-link {
    display: inline-block;
    background: var(--rask-accent-soft);
    color: var(--rask-accent);
    padding: 0.18rem 0.6rem;
    border-radius: 999px;
    font-weight: 600;
}

.see-also-link:hover {
    background: var(--rask-accent);
    color: #fff;
}
