/* Project-wide CSS foundation: reset, self-hosted Inter, brand CSS variables,
   and global element styles (buttons incl. loading spinner, inputs, labels). */

/* --- self-hosted Inter (SIL Open Font License) --- */
@font-face { font-family: "Inter"; font-weight: 400; font-display: swap;
  src: url("/static/fonts/inter-latin-400-normal.da03732a27e1.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 500; font-display: swap;
  src: url("/static/fonts/inter-latin-500-normal.51205681a1ba.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 600; font-display: swap;
  src: url("/static/fonts/inter-latin-600-normal.2ede57db1a3a.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-weight: 700; font-display: swap;
  src: url("/static/fonts/inter-latin-700-normal.8ca0a5155296.woff2") format("woff2"); }

/* --- design tokens; brand colours default here and are overridden per-brand
       by the inline :root block base.html renders from brand_css_vars --- */
:root {
  --brand-gradient-from: #04a7e0;
  --brand-gradient-via: #0087cc;
  --brand-gradient-to: #00659b;
  --brand-accent: #00538a;
  --font-sans: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --radius: 10px;
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
}

/* --- minimal reset --- */
*, *::before, *::after { box-sizing: border-box; }
/* An explicit background-color on the *root* (html) — not the implicit system
   default — so iOS 26 Safari tints the browser toolbars (esp. the bottom search
   bar) white instead of falling back to grey system chrome. Login paints its
   own fixed brand-blue backdrop, which wins at the viewport edges. */
html, body { margin: 0; padding: 0; background-color: #fff; }
body { font-family: var(--font-sans); color: #1a1a1a; line-height: 1.5;
  -webkit-font-smoothing: antialiased; }
img { max-width: 100%; display: block; }

/* --- forms --- */
label { font-weight: 600; display: block; margin-bottom: 0.35rem; }
input[type="text"], input[type="email"], input[type="password"] {
  width: 100%; padding: 0.6rem 0.75rem; border: 1px solid #cfd6dd;
  border-radius: var(--radius); font: inherit; background: #fff; color: #1a1a1a; }
input:focus { outline: none; border-color: var(--brand-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-accent) 25%, transparent); }

/* --- buttons --- */
button, input[type="submit"] {
  font: inherit; font-weight: 600; cursor: pointer; border: none;
  border-radius: var(--radius); padding: 0.65rem 1.1rem;
  background: var(--brand-accent); color: #fff; transition: filter 0.15s ease; }
button:hover, input[type="submit"]:hover { filter: brightness(1.08); }
button:active, input[type="submit"]:active { filter: brightness(0.95); }
button:disabled, input[type="submit"]:disabled { cursor: default; opacity: 0.7; }

/* loading state: a spinning ring before the label, in the button's OWN text colour
   (currentColor) so it stays visible on every variant — accent (white text), danger
   (red text on white), and plain buttons alike. Pure CSS. */
button.is-loading::before, input[type="submit"].is-loading::before {
  content: ""; display: inline-block; width: 0.9em; height: 0.9em;
  margin-right: 0.5em; vertical-align: -0.1em; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent; opacity: 0.85;
  animation: pms-spin 0.6s linear infinite; }
@keyframes pms-spin { to { transform: rotate(360deg); } }

/* --- field help: a "?" behind the label, its text in a hover/pinned bubble ------------
   Markup: templates/partials/_field_help.html, rendered for EVERY form field with a
   help_text. This lives in base.css and not in app.css because the field template is
   project-wide: standalone pages in the gate look ("Passwort ändern") load base.css only,
   and app.css rules would leave a naked "?" with an unstyled bubble there. For the same
   reason the colours below are literals rather than app.css design tokens, and the glyph
   is a text character rather than a Bootstrap icon. Pinning: static/js/base.js. */
/* The wrapper hugs the button (inline-flex, not inline-block), so `vertical-align: middle`
   aligns the circle itself with the label's x-height midpoint. As an inline-block its box was
   a whole line box — half a line taller than the icon — and the button hung at the bottom of
   it, which put the "?" a visible 2-3px below the label text. Hugging also anchors the bubble
   to the button instead of to that taller box. */
.fhelp { position: relative; display: inline-flex; vertical-align: middle; }
.fhelp-btn {
  /* Undo the global accent-button styling above — this is a quiet inline marker, not an
     action. Only the shape is restated; font and focus behaviour stay the project's. */
  padding: 0; background: #fff; color: #6b7680; border: 1px solid #b6c0ca;
  border-radius: 50%; width: 1.05rem; height: 1.05rem;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.68rem; font-weight: 700; line-height: 1;
  margin-left: 0.35rem;
  transition: color 0.15s ease, border-color 0.15s ease;
}
/* The global button:hover brightness filter does nothing on white and would only fight the
   colour change below. */
.fhelp-btn:hover, .fhelp-btn:active { filter: none; }
.fhelp-btn:hover, .fhelp-btn:focus-visible, .fhelp.is-pinned .fhelp-btn {
  color: var(--brand-accent); border-color: var(--brand-accent);
}
.fhelp-bubble {
  display: none; position: absolute; z-index: 60;
  top: calc(100% + 6px); left: 0;
  width: max-content; min-width: 12rem; max-width: 22rem;
  padding: 0.55rem 0.7rem;
  background: #fff; border: 1px solid #dbe2e8; border-radius: var(--radius);
  box-shadow: 0 8px 24px rgb(16 34 51 / 0.16);
  /* Labels are bold and may be centred by their container — the help text is prose. */
  font-size: 0.8rem; font-weight: 400; line-height: 1.45; text-align: left;
  white-space: normal; color: #33404a; cursor: auto;
}
.fhelp:hover > .fhelp-bubble,
.fhelp-btn:focus-visible + .fhelp-bubble,
.fhelp.is-pinned > .fhelp-bubble { display: block; }
/* Near the right window edge base.js flips the bubble so it grows leftwards instead of
   running off screen. */
.fhelp--flip > .fhelp-bubble { left: auto; right: 0; }

/* Opt-in variant for a "?" that sits inside a clipping box — a card edge, or a list with its
   own overflow-y (the ring legend in metering.css is the case this was built for). An
   absolutely positioned bubble is clipped by such an ancestor no matter which way it opens,
   and no amount of top/bottom juggling gets it out: a short list simply has less room above
   it than the bubble is tall. `fixed` takes the bubble out of that box altogether and lets
   base.js measure it against the WINDOW, which is the only edge that really constrains it.
   The offsets are left to the script deliberately — there is no static position that is right
   for a box the page can scroll. Without JavaScript the bubble stays where the CSS below it
   puts it, which is why the fallback rules in the app stylesheets remain. */
.fhelp--float > .fhelp-bubble { min-width: 0; max-width: none; }
.fhelp--float.is-placed > .fhelp-bubble {
  position: fixed;
  /* The fallback offsets an app stylesheet sets for the no-script case have to be undone here,
     not merely overridden: `top` and `bottom` together do not over-constrain a box of automatic
     height -- they DEFINE it. A left-over `bottom: calc(100% + 6px)`, which under `fixed` means
     the viewport rather than the row, squashed the bubble to a 19px sliver. Same for right. */
  bottom: auto; right: auto; height: auto;
}
