/* =============================================================================================
   tv-theme.css — everything that bridges the tokens to MudBlazor and must beat MudBlazor.min.css.

   Mirrors TimeView-Web/UI/.../TSO.TimeView.Shared.Components/wwwroot/tv-theme.css, adapted from
   Syncfusion to MudBlazor. Manually synced; see the header of tv-tokens.css.

   Load order (Components/App.razor): MudBlazor.min.css → MDI → tv-tokens.css → THIS FILE →
   quill.snow.css → app.css → the scoped bundle.

   This file defines NO tokens at :root. tv-tokens.css owns them; a second :root definition in a
   later sheet silently wins and the documented one never renders. The one exception is the
   scrollbar trio below, which are local aliases and exist nowhere else.
   ============================================================================================= */

/* ---------------------------------------------------------------------------------------------
   Base
   --------------------------------------------------------------------------------------------- */

/* font-size belongs on body alone. Setting it on html too compounds: html would compute to
   0.875 × 16px = 14px, and body's own 0.875rem would then resolve against *that* new root,
   giving 12.25px — with every --tv-space-* and --tv-text-* token, all of them rem-based,
   silently shrunk to 87.5 % of its designed value. Leave the root at the browser default so
   1rem stays 16px and the scale means what it says. */
html {
    margin: 0;
    padding: 0;
    background-color: var(--tv-body-bg, hotpink);
}

body {
    margin: 0;
    padding: 0;
    font-family: var(--tv-font-sans);
    font-size: var(--tv-text-body);
    line-height: var(--tv-leading-normal);
    background-color: var(--tv-body-bg, hotpink);
    color: var(--tv-body-fg, hotpink);
}

/* MudBlazor paints the canvas on .mud-layout / .mud-main-content; html carries the overscroll
   area, so without this a dark theme leaves a light rim at the edges of the viewport. */
body[data-theme="dark"],
html[data-theme="dark"] {
    color-scheme: dark;
}

body[data-theme="light"],
html[data-theme="light"] {
    color-scheme: light;
}

a {
    color: var(--tv-accent, hotpink);
}

/* Bootstrap is not loaded, so the stock focus ring would be the browser default. Two-tone:
   a thin separating ring in the surface colour, then the accent. */
:focus-visible {
    outline: none;
    box-shadow: 0 0 0 0.125rem var(--tv-focus-ring-inner, hotpink),
                0 0 0 0.25rem var(--tv-focus-ring, hotpink);
}

/* Routes.razor moves focus to the h1 programmatically after navigation (FocusOnNavigate
   Selector="h1"); a ring there is noise, not signal, since the user did not press Tab to get it.
   Scoped to :not(:focus-visible) rather than a blanket h1:focus, so a real keyboard focus (Shift+
   Tab back onto the heading, a skip link that targets it, ...) still gets the ring — only the
   programmatic, non-keyboard focus loses it. */
/* FocusOnNavigate (Routes.razor) lands focus on the page h1 after every navigation, giving it
   tabindex="-1". Script-driven focus still matches :focus-visible, so without this a ring flashes
   round the page title on every single page change. Scoped to tabindex="-1" deliberately: that
   value means programmatic-only and not keyboard-reachable. An h1 ever made genuinely focusable
   (tabindex="0") is not matched here and keeps its indicator. */
h1[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible {
    outline: none;
    box-shadow: none;
}

/* ---------------------------------------------------------------------------------------------
   Scrollbars
   --------------------------------------------------------------------------------------------- */

:root {
    --scrollbar-track-color: var(--tv-surface-alt, hotpink);
    --scrollbar-thumb-color: color-mix(in srgb, currentColor 30%, transparent);
    --scrollbar-thumb-hover-color: color-mix(in srgb, currentColor 45%, transparent);
}

* {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}

*::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
    background: var(--scrollbar-track-color);
}

*::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar-thumb-color);
    border-radius: 6px;
    border: 2px solid var(--scrollbar-track-color);
    /* The track token is a translucent color-mix, so without padding-box the thumb's own
       background paints through its border and the 2px inset pill gap disappears. */
    background-clip: padding-box;
}

*::-webkit-scrollbar-thumb:hover {
    background-color: var(--scrollbar-thumb-hover-color);
}

/* ---------------------------------------------------------------------------------------------
   MDI glyphs inside MudBlazor components

   MudBlazor's own icons are inline SVG sized by .mud-icon-root. Our icons are MDI font glyphs in
   an <i class="mdi mdi-*">, so they get none of that sizing and land on the text baseline with
   the wrong optical weight. These rules give them the same box.
   --------------------------------------------------------------------------------------------- */

.mdi {
    line-height: 1;
}

.mud-button-root .mdi,
.mud-button-icon-start .mdi,
.mud-button-icon-end .mdi,
.mud-icon-button .mdi {
    font-size: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.mud-nav-link .mdi,
.mud-nav-link-icon .mdi {
    font-size: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.mud-chip .mdi {
    font-size: 1rem;
}

/* ---------------------------------------------------------------------------------------------
   Button hierarchy (.tv-btn-*)

   Every button in the portal is a <TvButton>, and its visual weight comes from Variant — nothing
   else. These classes carry that weight in the markup, so a reviewer can read the hierarchy of a
   surface from the class names alone without resolving MudBlazor's Variant/Color pair.

   Rules: exactly one Primary per surface; an icon-only button is never Primary; never express
   weight through a status or brand colour.
   --------------------------------------------------------------------------------------------- */

.mud-button-root.tv-btn {
    text-transform: none;
    gap: var(--tv-space-2);
}

/* MudBlazor upper-cases tab labels by default. The portal sets its own case in the markup —
   Danish sentence case everywhere — so the transform only ever corrupts it (and breaks the
   "FORHÅNDSVISNING" style of long compound words). */
.mud-tabs .mud-tab {
    text-transform: none;
}

/* Primary — the one action the surface exists for. Solid accent fill with its own foreground,
   because a fill cannot inherit a contrast guarantee from the theme. */
.mud-button-root.tv-btn-primary {
    background-color: var(--tv-accent, hotpink);
    color: var(--tv-accent-fg, hotpink);
}

.mud-button-root.tv-btn-primary:hover {
    background-color: color-mix(in srgb, var(--tv-accent, hotpink) 85%, var(--brand-black, hotpink));
}

/* Secondary (the default) — outline. Available, but not the point of the surface. */
.mud-button-root.tv-btn-secondary {
    border-color: var(--tv-border-color, hotpink);
    color: var(--tv-accent, hotpink);
}

.mud-button-root.tv-btn-secondary:hover {
    border-color: var(--tv-accent, hotpink);
    background-color: color-mix(in srgb, var(--tv-accent, hotpink) 8%, transparent);
}

/* Tertiary — borderless. Dismiss, cancel, low-stakes toggles. */
.mud-button-root.tv-btn-tertiary {
    border: none;
    color: inherit;
}

.mud-button-root.tv-btn-tertiary:hover {
    background-color: var(--tv-color-hover, hotpink);
}

/* Destructive — irreversible. */
.mud-button-root.tv-btn-destructive {
    background-color: var(--palette-red-deep, hotpink);
    color: var(--brand-white, hotpink);
}

.mud-button-root.tv-btn-destructive:hover {
    background-color: color-mix(in srgb, var(--palette-red-deep, hotpink) 85%, var(--brand-black, hotpink));
}

.mud-button-root.tv-btn .mud-button-label {
    gap: var(--tv-space-2);
}

/* Touch targets.

   WCAG 2.5.8 (AA) sets the floor at 24×24 CSS px; the practical target on a phone is 44×44 —
   Apple HIG and Material agree. MudBlazor's icon buttons land at roughly 40px at Medium and 30px
   at Small, so the Small ones (used for comment dismiss, reply-cancel, changelog actions) are
   below even the AA floor once a finger is involved.

   Scoped to `pointer: coarse` so the denser desktop rhythm is untouched: this is a finger
   problem, not a viewport problem, and a narrow window on a laptop should not get phone spacing.
   Padding rather than width so the glyph stays centred and the hit area grows around it. */
@media (pointer: coarse) {
    .mud-icon-button,
    .mud-button-root,
    .mud-nav-link {
        min-height: 44px;
    }

    .mud-icon-button {
        min-width: 44px;
    }
}

/* ---------------------------------------------------------------------------------------------
   Dark theme

   MudBlazor's own dark palette comes from PortalTheme.PaletteDark, and every token above reads
   --mud-palette-*, so almost everything follows for free. This block is deliberately small: it
   only corrects the few values a palette cannot express.
   --------------------------------------------------------------------------------------------- */

body[data-theme="dark"] {
    /* A 10 % black shadow is invisible on a dark canvas; elevation has to be stated harder. */
    --tv-shadow-flyout: 0 0.5rem 2rem rgba(0, 0, 0, 0.55);
    --tv-shadow-flyout-hover: 0 1rem 3rem rgba(0, 0, 0, 0.7);

    /* The brand hues do not track the theme, so a brand fill's foreground cannot be left to the
       theme either. White holds on all five (see the contrast table in tv-tokens.css). */
    --tv-accent-fg: var(--brand-white, hotpink);
}
