/*
   Five things live here, for five different reasons:

   1. The pre-Blazor boot phase: the window where no component exists yet to
      style, which MudBlazor's theme (Theme/AuftragTheme.cs) cannot reach
      because it hasn't rendered.
   2. Browser-native surfaces (text selection, the scrollbar): still
      unreachable after boot, but for a different reason -- MudThemeProvider
      has no property for arbitrary raw CSS (its PseudoCss.Scope is the
      selector wrapping its own generated variable block, not an injection
      point; using it that way silently breaks every theme variable). These
      values are duplicated from AuftragTheme.cs's constants by hand, same as
      infra/keycloak/themes/auftragli/login/resources/css/auftragli.css does
      for the same reason: no shared source reaches a plain CSS file.
   3. The minimum touch target, below. CLAUDE.md's "scope it in .razor.css,
      never a global stylesheet" is about one component's own styling; this is
      the opposite -- a floor that has to hold for every MudBlazor control the
      app renders, in whichever component renders it. CSS isolation cannot
      express that without ::deep duplicated into both layouts, and MudBlazor's
      theme has no property for control height.
   4. The skip link, for the same reason as (3): both layouts render one, and an
      isolated stylesheet would carry the same declaration twice.
   5. The keyboard focus ring, below -- one rule for every control the app
      renders, which is (3)'s reason again.
*/

/*
   Keyboard focus.

   MudBlazor ships `a:focus-visible { outline: none }`, `button:focus { outline:
   none }` and `.mud-rating-root:focus-visible { outline: none }`, and replaces
   them for buttons with a background tint that is invisible on a filled one and
   with nothing at all on a link. So every job title in all three tables, every
   nav link, every footer link and the star rating had no visible focus at all --
   which is what the table cells were turned into real anchors *for*.

   Only the style is missing: MudBlazor already leaves outline-color and
   outline-width set (measured `rgb(0,43,127) none 3px` on a job link), so this
   restores what its reset took and nothing more. WCAG 2.4.7.

   :focus-visible rather than :focus, so a mouse click does not leave a ring
   behind. Home.razor.css keeps its own white ring for the two navy surfaces,
   where this blue would disappear.
*/
:focus-visible,
a:focus-visible,
button:focus-visible,
.mud-button-root:focus-visible,
.mud-nav-link:focus-visible,
.mud-chip:focus-visible,
.mud-rating-root:focus-visible,
.mud-table-row:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/*
   Skip link. Both layouts write out a real <main> rather than leaving the
   landmark to MudMainContent, on the grounds that the app needs something to
   skip to -- this is the control that skips. Without it a keyboard user tabs
   the whole drawer again on every navigation.

   Off-screen until focused, then pinned over the app bar. No transition: it
   has to be at rest the instant it takes focus. The colours come from the
   theme's own variables, unlike the boot-phase block above -- by the time this
   can be focused, MudThemeProvider has rendered them.
*/
.skip-link {
    position: fixed;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 2000;
    padding: 0.5rem 1rem;
    border: 1px solid var(--mud-palette-primary);
    border-radius: var(--mud-default-borderradius);
    background-color: var(--mud-palette-surface);
    color: var(--mud-palette-primary);
    font-size: var(--mud-typography-button-size);
    font-weight: 600;
    text-decoration: none;
    transform: translateY(-200%);
}

.skip-link:focus {
    transform: translateY(0);
}

html, body {
    margin: 0;
    padding: 0;
    font-family: Inter, "Segoe UI", Helvetica, Arial, sans-serif;
    background-color: #f4f6fa;
}

/* Both layouts' app bar. Global rather than scoped per layout, for the reason
   the skip-link rule above is: AppLayout and MarketingLayout render the same
   bar, and an isolated stylesheet would mean the same rules in both files. */
.app-bar {
    border-bottom: 1px solid var(--mud-palette-divider);
}

/* The flag band. Liechtenstein's blue, red and gold as one rule, under the app
   bar and again above the footer, so the shell is bracketed by it.

   A custom property and not two copies of the gradient: it is drawn in two
   files now -- here for the bar, and AppFooter.razor.css for the footer, which
   is scoped and cannot see a class defined in this one -- and a flag that
   differs between the top and the bottom of the same page is the kind of thing
   nobody notices until it ships.

   The first two colours now equal Primary and Error -- the palette is the
   flag's own values, see DESIGN.md's One Palette Rule -- and are still written
   out rather than as var(--mud-palette-*), for one reason only: a flag has
   fixed colours and must not follow a re-theme. (Not because the variables are
   out of reach. They resolve at render time, which is why the focus ring above
   uses one.) Crown Gold has no palette token at all; at 2.42:1 on white it can
   never carry text, so this band is the only place it appears. */
:root {
    /* Platform Navy and Ink On Navy, for the scoped stylesheets that draw the
       navy surfaces (footer, home bands, registration scrim). See DESIGN.md. */
    --platform-navy: #00246e;
    --ink-on-navy: #d7e2f7;

    /* The two radii above the theme's own (buttons, fields, chips). See
       DESIGN.md, Shapes. */
    --card-radius: 12px;
    --sheet-radius: 16px;

    --flag-band: linear-gradient(
        to right,
        #002b7f 0 70%,
        #ce1126 70% 88%,
        #c9a227 88% 100%
    );
}

/* A pseudo-element rather than a border, because a border cannot carry three
   colours; hard gradient stops rather than three divs, because the bar is a
   flex row and three more children would have to be excluded from its spacing.
   The bar is fixed, so an absolutely-positioned child needs no positioned
   ancestor of its own.

   The three background longhands align this band with the footer's, which
   repeats them. The bar spans the window while the footer sits inside
   .mud-main-content, inset by the drawer above md -- one gradient in percent
   over two widths put the red edge 72px apart. Drawn at window width and pinned
   to the edge both share, so nothing here needs the drawer's width.

   Right and not left: a fixed element resolves width:100% against the viewport
   without the scrollbar, 100vw includes it. Only at the right edge does that
   difference cancel. */
.app-bar::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 3px;
    background-image: var(--flag-band);
    background-size: 100vw 100%;
    background-position: right top;
    background-repeat: no-repeat;
}

.app-bar .app-bar-rule {
    height: 28px;
}

/* Sticky footer: the shell fills the viewport so AppFooter's own margin-top:auto
   has something to push against. Without this the rule was inert -- .mud-main-content
   is not a flex container and is only as tall as its content, so on a short page
   (Impressum, Datenschutz, an empty list) the footer sat halfway up the screen
   with ledger-paper below it.
   min-height rather than height, so long pages still scroll normally; MudBlazor
   sets border-box globally, so the app-bar padding .mud-main-content already
   carries counts inside the 100dvh rather than adding a scrollbar to every page. */
.mud-main-content {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

.mud-main-content > main {
    flex: 1 0 auto;
}

.loading-brand {
    text-align: center;
    padding-top: 14vh;
}

/* The mark sits above the wordmark on the cold-boot frame, where there is room
   for it to read as a mark rather than as a favicon. */
.loading-mark {
    display: block;
    margin: 0 auto 0.75rem;
}

/* Sizes duplicated from AuftragTheme's H4 and Body2 steps by hand, for the
   reason at the top of this file: the theme has not rendered yet, so no
   --mud-* variable exists during the boot phase. */
.loading-wordmark {
    font-size: 1.125rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: #00246e;
}

.loading-tagline {
    margin-top: 0.35rem;
    font-size: 0.875rem;
    color: #505b6f;
}

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 3rem auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke: #d5dde8;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:last-child {
    stroke: #002b7f;
    stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
    transition: stroke-dasharray 0.05s ease-in-out;
}

/* Centred on the ring by flowing after it and being pulled back up, not by an
   absolute offset from the top of the viewport.

   The previous rule pinned this to `calc(20vh + 3.25rem)` while .loading-brand
   above it starts at 14vh -- two different vh multipliers for one stack, so the
   text drifted out of the ring as the viewport grew, and any change to the
   brand block moved the ring without moving the text. Adding the mark is what
   surfaced it: the ring dropped ~3.9rem and the text stayed put, landing on the
   tagline. 1rem is the ring's bottom margin, 4rem its half-height, 0.75rem half
   a line -- so the text's centre lands on the ring's centre whatever sits above. */
.loading-progress-text {
    position: relative;
    margin-top: calc(-1rem - 4rem - 0.75rem);
    text-align: center;
    color: #505b6f;
}

.loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Wird geladen…");
}

#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    padding: 0.75rem 1.25rem;
    background: #ffe8e8;
    color: #7a1220;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/*
   Touch targets. MudBlazor's default button height is 37px; on a phone that is
   under every published minimum (WCAG 2.5.5, Material's 48dp, Apple's 44pt),
   and this app counted 8-14 undersized controls per screen.

   Raised here rather than per component: it is one rule for every button the
   app will ever render, and MudBlazor exposes no theme property for control
   height. Written as a min-height so a button with taller content still grows.

   Scoped to coarse pointers on purpose -- a mouse does not need a 44px target,
   and enlarging every desktop button would change the density of every dense
   surface (table rows, icon buttons in lists) for no benefit.
*/
@media (pointer: coarse) {
    .mud-button-root,
    .mud-nav-link {
        min-height: 44px;
    }

    /* Icon buttons are square, so the width has to come with the height or the
       target is still a 44x24 sliver. */
    .mud-icon-button {
        min-width: 44px;
        min-height: 44px;
    }

    /* Only the clickable ones. MudBlazor adds mud-clickable to a chip that acts
       as a control (the job list's status filter) and leaves it off one that
       only displays a value (JobStatusChip), which appears inside table rows
       and cards where 44px would be dead weight. */
    .mud-chip.mud-clickable {
        min-height: 44px;
    }

    /* The wordmark is the app bar's "home" link in both layouts, so it is a
       target like any other. Written here rather than in each layout's own
       isolated stylesheet, which would mean the same ::deep rule twice. */
    .mud-appbar a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }
}

/*
   Chips on the theme's radius.

   MudBlazor hard-codes 16px on .mud-chip and 12px on the small size, and
   DefaultBorderRadius does not reach them -- so the status chip on every job
   row and card, and both filter chip sets, rendered as pills outside
   DESIGN.md's three radii. Here rather than in a .razor.css for the reason at
   the top of this file: it is one rule for every chip the app renders, in
   whichever component renders it.

   The three size classes are spelled out because MudBlazor sets the radius on
   them, not on .mud-chip -- a bare .mud-chip rule is one specificity step short
   and loses silently, which is exactly what it did here first.
*/
.mud-chip.mud-chip-size-small,
.mud-chip.mud-chip-size-medium,
.mud-chip.mud-chip-size-large {
    border-radius: var(--mud-default-borderradius);
}

::selection {
    background-color: #002b7f;
    color: #ffffff;
}

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

::-webkit-scrollbar-track {
    background: #f4f6fa;
}

::-webkit-scrollbar-thumb {
    background-color: #b7c0ce;
    border: 3px solid #f4f6fa;
    border-radius: var(--mud-default-borderradius);
}

::-webkit-scrollbar-thumb:hover {
    background-color: #505b6f;
}
