/* === DESIGN TOKENS === */
:root {
  /* Brand */
  --brand: #204a80;
  --brand-hover: #173a67;
  --accent: #3767c7;
  --focus-ring: #0f62fe;
  --focus-shadow: rgba(15, 98, 254, 0.28);
  --on-brand: #ffffff;
  --on-warning: #ffffff;

  /* Text */
  --text-primary: #111827;
  --text-secondary: #253041;
  --text-muted: #4b5563;
  --text-faint: #556274;

  /* Surfaces */
  --bg-page: #edf2f8;
  --bg-card: #ffffff;
  --bg-subtle: #f6f8fb;
  --bg-code: #eef2f7;
  --bg-elevated: #ffffff;
  --bg-elevated-strong: #ffffff;

  /* Borders */
  --border-light: #d7dfeb;
  --border: var(--border-light);

  /* Error. --error is text on --error-bg in the feedback block, the status tag and
     .error. The value before 2026-09-25 gave 3.95:1 there, below the 4.5:1 of WCAG 2.2
     AA (1.4.3). This value gives 4.74:1 on --error-bg and 5.16:1 on --bg-subtle, the
     ground of a hovered row. */
  --error: #c03636;
  --error-hover: #a83030;
  --error-bg: #fdeaea;

  /* Status */
  --success: #166534;
  --warning: #b45309;
  --warning-bg: #fdf1e3;
  --danger: #b42318;

  /* Chart categories (.app-pie-slice-N, see style.app.css)
     One fixed order, never cycled. The order keeps each neighbouring pair apart for a
     reader with a color vision deficiency. Three light steps sit below 3:1 on the card,
     thus a chart always prints each value as text beside the swatch. */
  --chart-1: #2a78d6;
  --chart-2: #eb6834;
  --chart-3: #1baf7a;
  --chart-4: #eda100;
  --chart-5: #e87ba4;
  --chart-6: #008300;
  --chart-7: #4a3aa7;
  --chart-8: #e34948;
  --chart-other: #8a94a6;

  /* Faculty colors (.app-pie-tone-faculty-*, see module/user/instruments/css)
     Each color is the one that www.upjs.sk uses for the faculty. TIP and UPJS have no faculty
     color there, thus TIP takes the unit color of the site and UPJS takes its base blue. */
  --faculty-lf: #C92432;
  --faculty-fvs: #006DB2;
  --faculty-tip: #A88800;
  --faculty-upjs: #164082;
  --faculty-ff: #F5AF00;
  --faculty-pf: #008338;
  --faculty-prf: #832472;

  /* Status tag surfaces (.app-status-tag — see style.app.css)
     Every value derives from a token above. No raw colour enters here, thus a change
     of --success or --error reaches the tag, and the dark palette needs no override:
     each base token already flips below. */
  --status-ok-bg: color-mix(in srgb, var(--success) 14%, var(--bg-card));
  --status-ok-text: var(--success);
  --status-ok-border: color-mix(in srgb, var(--success) 32%, var(--bg-card));
  --status-warn-bg: var(--warning-bg);
  --status-warn-text: var(--warning);
  --status-warn-border: color-mix(in srgb, var(--warning) 32%, var(--bg-card));
  --status-error-bg: var(--error-bg);
  --status-error-text: var(--error);
  --status-error-border: color-mix(in srgb, var(--error) 32%, var(--bg-card));
  --status-neutral-bg: var(--bg-subtle);
  --status-neutral-text: var(--text-secondary);
  --status-neutral-border: var(--border-light);

  /* Overlays */
  --overlay-scrim: rgba(0, 0, 0, 0.45);      /* modal and drawer backdrop */
  --surface-highlight: rgba(255, 255, 255, 0.04); /* 1px inset top highlight */

  /* Shadows */
  --shadow-sm: 0 2px 12px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 4px 24px rgba(0, 0, 0, 0.06);

  /* Radii */
  --radius: 4px;
  --radius-sm: 2px;
  --radius-md: 4px;
  --radius-lg: 6px;
  --radius-xl: 8px;
  --radius-2xl: 10px;
  --radius-pill: 999px;

  /* Font */
  --font-sans: "Aptos", "IBM Plex Sans", "Segoe UI Variable Text", "Segoe UI", "Source Sans 3", "Noto Sans", sans-serif;
  --font-heading: "Aptos Display", "IBM Plex Sans", "Segoe UI Variable Display", "Segoe UI", "Source Sans 3", sans-serif;
  --font-mono: "IBM Plex Mono", "Cascadia Code", "SFMono-Regular", "Consolas", monospace;

  /* Typography scale. A rule takes a font size from this scale, never a raw rem value.
     A -sm step sits just below the step of the same name. */
  --fs-2xs: 0.5625rem;     /* 9px — the initials of the compact avatar (its size is in em) */
  --fs-xs: 0.625rem;       /* 10px — tiny labels, badge text */
  --fs-label: 0.6875rem;   /* 11px — UPPERCASE section labels */
  --fs-sm: 0.75rem;        /* 12px — help text, secondary info */
  --fs-base-sm: 0.8125rem; /* 13px — small body, feedback messages */
  --fs-body: 0.875rem;     /* 14px — body text (default) */
  --fs-body-lg: 0.9375rem; /* 15px — chat messages, prominent body */
  --fs-base: 1rem;         /* 16px — base / form controls */
  --fs-md: 1.0625rem;      /* 17px — dialog titles, emphasized body */
  --fs-lg: 1.125rem;       /* 18px — card titles, h3 of a guide */
  --fs-xl-sm: 1.25rem;     /* 20px — h2 of a guide on a phone */
  --fs-xl: 1.375rem;       /* 22px — page sub-headings */
  --fs-2xl-sm: 1.5rem;     /* 24px — a stat value and a hero title on a phone */
  --fs-2xl: 1.625rem;      /* 26px — section stat values */
  --fs-3xl: 1.75rem;       /* 28px — the login title, h1 of a guide */
  --fs-stat: 2rem;         /* 32px — primary stat display */

  /* Spacing scale (4px grid). --space-N is N x 4px. A half step (--space-N-5) is
     (N + 0.5) x 4px, for a value between two steps. A value off the 4px grid (1px,
     3px, 7px and so on) stays a number in the rule. */
  --space-0-5: 2px;
  --space-1: 4px;
  --space-1-5: 6px;
  --space-2: 8px;
  --space-2-5: 10px;
  --space-3: 12px;
  --space-3-5: 14px;
  --space-4: 16px;
  --space-4-5: 18px;
  --space-5: 20px;
  --space-5-5: 22px;
  --space-6: 24px;
  --space-7: 28px;
  --space-8: 32px;
  --space-9: 36px;
  --space-10: 40px;
  --space-12: 48px;

  /* Stacking layers, from the lowest. A new layer takes a token here, never a number
     in a rule. The values are the ones the rules used before the tokens existed. */
  --z-topbar: 50;
  --z-sidebar-overlay: 99;
  --z-sidebar: 100;
  --z-float: 1000;            /* the chat widget, the attendance modal */
  --z-skip-link: 2000;
  --z-dialog: 9000;

  /* Elevation */
  --focus-ring-shadow: 0 0 0 4px var(--focus-shadow);
  --focus-ring-shadow-sm: 0 0 0 2px var(--focus-ring);
  --shadow-dialog: 0 20px 60px rgba(0, 0, 0, 0.25);

  /* Animation */
  --transition-fast: 0.15s;
  --transition-normal: 0.25s;
  --transition-slow: 0.4s;
  --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);

  /* Control and icon sizes. --control-size-sm is the side of a small square control, for
     example a toolbar button or a spinner. --icon-box is the side of an icon in a brand box. */
  --control-size-sm: 2rem;
  --icon-box: 40px;

  /* Line heights. --lh-body is for running text. --lh-tight is for a card description.
     --lh-heading is for a large heading. */
  --lh-body: 1.6;
  --lh-tight: 1.5;
  --lh-heading: 1.2;

  /* The letter spacing of a small caps label. */
  --tracking-label: 0.5px;

  /* The outline of a focused control, for a control that draws its own outline. */
  --focus-outline: 2px solid var(--focus-ring);

  /* Shell sizing */
  --shell-rail-width: 3.5rem;
  --shell-sidebar-width: 16.25rem;
  --shell-sidebar-width-mobile: 17.5rem;
  --shell-header-height: 3.5rem;
  --shell-header-height-mobile: 3rem;
  --shell-control-size: 2.25rem;
  --shell-control-size-compact: var(--control-size-sm);
  --shell-icon-size: 1.25rem;
  --shell-avatar-size: 2.5em;
  --shell-avatar-size-compact: 2.222222em;
}

/* === DARK THEME ===
 * Override block for all color tokens — structure mirrors :root exactly.
 * Toggled via JS: document.documentElement.setAttribute('data-theme', 'dark').
 * themeController.js persists the preference in localStorage('theme').
 * When adding a new color token, always add a dark-mode counterpart here.
 * Light backgrounds (#edf2f8 → #0b1220), surfaces (#fff → #182235), borders muted.
 */
[data-theme="dark"] {
  color-scheme: dark;

  /* Brand */
  --brand: #9fc3ff;
  --brand-hover: #c2d7ff;
  --accent: #7fb0ff;
  --focus-ring: #c2d7ff;
  --focus-shadow: rgba(159, 195, 255, 0.34);
  --on-brand: #08111f;
  --on-warning: #1f1600;

  /* Text */
  --text-primary: #f8fbff;
  --text-secondary: #e7eef8;
  --text-muted: #c3d0e0;
  --text-faint: #9fb0c7;

  /* Surfaces */
  --bg-page: #0b1220;
  --bg-card: #182235;
  --bg-subtle: #22304a;
  --bg-code: #111b2c;
  --bg-elevated: #0f1724;
  --bg-elevated-strong: #121c2b;

  /* Borders */
  --border-light: #44546d;
  --border: var(--border-light);

  /* Error */
  --error: #ff8f8f;
  --error-hover: #ffb0b0;
  --error-bg: #472427;

  /* Status */
  --success: #7ee2a8;
  --warning: #ffd166;
  --warning-bg: #443616;
  --danger: #ff9b8f;

  /* Chart categories: the same eight hues, stepped for the dark card. */
  --chart-1: #3987e5;
  --chart-2: #d95926;
  --chart-3: #199e70;
  --chart-4: #c98500;
  --chart-5: #d55181;
  --chart-6: #008300;
  --chart-7: #9085e9;
  --chart-8: #e66767;
  --chart-other: #7a869b;

  /* Faculty colors: the hues of the light theme, lifted to 3:1 on the dark card. */
  --faculty-lf: #CD2935;
  --faculty-fvs: #0870B5;
  --faculty-tip: #A88800;
  --faculty-upjs: #406CB2;
  --faculty-ff: #F5AF00;
  --faculty-pf: #008338;
  --faculty-prf: #A74793;


  /* Overlays */
  --overlay-scrim: rgba(0, 0, 0, 0.45);
  --surface-highlight: rgba(255, 255, 255, 0.04);

  /* Shadows */
  --shadow-sm: 0 2px 12px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 4px 24px rgba(0, 0, 0, 0.3);
}

/* === RESET ===
 * Global reset + typography baseline.
 * Key classes:
 *   .skip-link        — keyboard-accessible "skip to content" link (visually hidden until :focus-visible)
 *   .visually-hidden  — SR-only content (accessibility, not display:none)
 *   .hidden           — utility: display:none !important (toggled by JS)
 * Focus ring: :focus-visible uses --focus-ring / --focus-shadow tokens.
 * Reduced motion: all transitions/animations compressed to 0.01ms.
 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: var(--font-sans);
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg-page);
  color: var(--text-primary);
  line-height: 1.55;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html {
  color-scheme: light;
  /* A thin scrollbar with a rounded thumb and no track. Every element inherits it. The tokens
     follow the theme, thus the thumb stays visible in the light and in the dark theme. */
  scrollbar-width: thin;
  scrollbar-color: var(--text-faint) transparent;
}

/* .hidden lives here, not in style.app.css: this file is the first-screen stylesheet, a
   blocking <link> in <head> of every page, including public/docs/index.html, which loads
   no style.app.css. A screen that hides an element before AUTH_SUCCESS (the login screen
   itself) or with no style.app.css at all (the public guide page) still needs it. */
.hidden {
  display: none !important;
}

h1,
h2,
h3,
h4,
h5,
h6,
.login-title,
.login-welcome,
.app-page-title,
.docs-brand h1,
.docs-hero h2 {
  font-family: var(--font-heading);
  letter-spacing: -0.02em;
}

a,
button,
input,
select,
textarea,
[tabindex]:not([tabindex="-1"]) {
  -webkit-tap-highlight-color: transparent;
}

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

:focus:not(:focus-visible) {
  outline: none;
}

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
  }
}

.skip-link {
  position: absolute;
  inset-inline-start: 16px;
  top: 12px;
  z-index: var(--z-skip-link);
  padding: var(--space-2-5) var(--space-3-5);
  border-radius: var(--radius-md);
  background: var(--brand);
  color: var(--on-brand);
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--transition-fast);
}

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

/* === SCREENS ===
 * Top-level visibility switch between login and app shell.
 * HTML: <div class="screen" id="loginScreen"> and <div class="screen" id="contentScreen">
 * JS: routeController.showScreen('loginScreen' | 'contentScreen')
 * Only one .screen is .active at a time. .active triggers fadeIn animation.
 * #contentScreen uses display:flex (not block) — never override to block.
 */
.screen {
  display: none;
  width: 100%;
  animation: fadeIn var(--transition-slow) ease-in;
}

.screen.active {
  display: block;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInOpacity {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* SVG sprite wrapper — inline styles ignored by Chrome on SVG/wrapper */
.svg-sprite-wrapper {
  display: none;
}

/* ==============================
   LOGIN PAGE
   Template: templates/login-screen.html
   Controller: authController.js (renderLoginScreen via routeController.js)
   ──────────────────────────────────────
   .login-page               full-viewport flex column
   .top-controls             lang + theme toggle (position:absolute top-right)
   .login-card               main card (max-width 520px)
   .login-btn                Microsoft sign-in button (background:--brand)
   .login-info-card          info link card below main card (hover: lift)
   .icon-brand / .icon-ms — SVG stroke/fill helpers
   .theme-icon-dark / .theme-icon-light — toggled by [data-theme="dark"]
   Responsive: ≤600px — card padding reduced, info cards stack
   ============================== */
.login-page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-10) var(--space-5) 0;
  position: relative;
  background: var(--bg-page);
}

/* --- Header --- */
.login-header {
  text-align: center;
  margin-bottom: var(--space-8);
}

/* A column of items with one gap. A module sets the gap with --stack-gap.
   Used by: the domain list of a proxy site, the list of an instrument, the links of the guides, the
   time range picker. The public guide page loads this sheet alone, thus the rule lives here. */
.app-stack {
  display: flex;
  flex-direction: column;
  gap: var(--stack-gap, var(--space-3));
}

/* A row of controls or facts, centred on one line, that wraps. A module sets the gap with --toolbar-gap.
   The public guide page loads this sheet alone, thus the rule lives here. */
.app-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--toolbar-gap, var(--space-4));
}

/* The footer of a page: <app-page> builds it from the children that name the slot footer. It closes the page with a note.
   The guide viewers use it for the source link, and the public guide page loads this sheet alone, thus the rule lives here. */
.app-page-footer {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--fs-base-sm);
}

/* A framed surface for a form, a summary or a card of facts.
   A module sets the look with these properties on the element: --panel-bg, --panel-border,
   --panel-radius, --panel-pad and --panel-shadow. A modifier sets them for the common cases.
   .is-card gives the card corner and the soft shadow. .is-roomy gives more padding.
   .is-subtle gives the quiet background. .is-danger marks a destructive step.
   A modifier has the weight of one class, thus a module sets the same property after it.
   The rule lives here, because the public guide page loads this sheet alone. */
.app-panel {
  background: var(--panel-bg, var(--bg-card));
  border: var(--panel-border, 1px solid var(--border-light));
  border-radius: var(--panel-radius, var(--radius-lg));
  padding: var(--panel-pad, var(--space-4));
  box-shadow: var(--panel-shadow, none);
}

:where(.app-panel).is-card {
  --panel-radius: var(--radius-md);
  --panel-shadow: var(--shadow-sm);
}

:where(.app-panel).is-roomy {
  --panel-pad: var(--space-6);
}

:where(.app-panel).is-subtle {
  --panel-bg: var(--bg-subtle);
}

:where(.app-panel).is-danger {
  --panel-bg: var(--error-bg);
  --panel-border: 1px solid var(--status-error-border);
}

/* An icon in a brand box: the service card, the stat card, the WiFi password card, the
   callout and the guide index. A module sets the side with --icon-box and the corner with
   --icon-radius. The tokens switch in dark mode, thus the box needs no dark rule of its own.
   The rule lives here, because the public guide page loads this sheet alone. */
.app-icon-badge {
  width: var(--icon-box);
  height: var(--icon-box);
  border-radius: var(--icon-radius, var(--radius-xl));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--on-brand);
  background: var(--brand);
  border: 1px solid var(--brand);
}

.app-icon-badge.is-warn {
  color: var(--on-warning);
  background: var(--warning);
  border-color: var(--warning);
}

/* The logo of the portal as a mask. The colour of the element shows through the logo.
   The login page and the shell both use it, thus it lives in this first-screen sheet. */
.app-logo-mask {
  -webkit-mask-image: url("../img/logo.svg");
  mask-image: url("../img/logo.svg");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.login-logo {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--space-4);
  background-color: var(--brand);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-sm);
}

.login-title {
  font-size: var(--fs-3xl);
  font-weight: 700;
  color: var(--brand);
  letter-spacing: -0.5px;
}

.login-subtitle {
  color: var(--text-muted);
  font-size: var(--fs-body);
  margin-top: var(--space-1);
}

/* --- Main Card --- */
.login-card {
  background: var(--bg-subtle);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-light);
  padding: var(--space-9);
  width: 100%;
  max-width: 520px;
  text-align: center;
}

.login-welcome {
  font-size: var(--fs-xl);
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-2);
  text-align: start;
}

.login-desc {
  color: var(--text-muted);
  font-size: var(--fs-body);
  text-align: start;
  margin-bottom: var(--space-7);
  line-height: var(--lh-tight);
}

/* --- Sign In Button --- */
.login-btn-wrapper {
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  padding: var(--space-2);
  margin-bottom: var(--space-6);
  background: var(--bg-card);
}

/* The link to the public password reset page. It sits under the sign-in button. */
.login-forgot {
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: 2.75rem;
  margin-block-end: var(--space-4);
  font-size: var(--fs-sm);
  color: var(--brand);
  text-decoration: underline;
}

.login-forgot:hover {
  color: var(--brand-hover);
}

.login-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2-5);
  background: var(--brand);
  color: var(--on-brand);
  border: 1px solid var(--brand);
  padding: var(--space-3-5) var(--space-6);
  font-size: var(--fs-body-lg);
  font-weight: 600;
  border-radius: var(--radius-md);
  cursor: pointer;
  box-shadow: none;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}

.login-btn:hover {
  background: var(--brand-hover);
  border-color: var(--brand-hover);
  transform: translateY(-1px);
}

.login-btn:active {
  transform: translateY(0);
}

/* --- SVG icon colors (single source of truth) --- */

.icon-brand {
  fill: none;
  stroke: var(--brand);
}

.icon-ms {
  fill: var(--on-brand);
  stroke: none;
}

/* --- Info Cards --- */
.login-info-cards {
  display: flex;
  gap: var(--space-4);
  margin-top: var(--space-8);
  width: 100%;
  max-width: 520px;
}

.login-info-card {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  background: var(--bg-card);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-light);
  text-decoration: none;
  color: inherit;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast);
}

.login-info-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
  border-color: var(--brand);
  background: var(--bg-subtle);
}

.login-info-card strong {
  font-size: var(--fs-base-sm);
  color: var(--text-primary);
  display: block;
}

.login-info-card p {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-top: var(--space-0-5);
}

.login-info-card svg {
  flex-shrink: 0;
  width: var(--icon-box);
  height: var(--icon-box);
  padding: var(--space-2);
  border-radius: var(--radius-xl);
  background: var(--brand);
  border: 1px solid var(--brand);
  color: var(--on-brand);
}

.login-info-card .icon-brand {
  stroke: var(--on-brand);
  color: var(--on-brand);
}

/* --- Bottom Links --- */
.login-bottom-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-top: var(--space-6);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.login-bottom-links a {
  color: var(--text-muted);
  text-decoration: none;
  transition: color var(--transition-normal);
}

.login-bottom-links a:hover {
  color: var(--brand);
}

.login-bottom-sep {
  color: var(--border-light);
}

/* --- Top Controls (lang + theme) --- */
.top-controls {
  position: absolute;
  top: 20px;
  inset-inline-end: 24px;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.top-control-btn {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
  background: var(--bg-subtle);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  padding: var(--space-1-5) var(--space-3);
  font-size: var(--fs-base-sm);
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition:
    color var(--transition-normal),
    border-color var(--transition-normal),
    box-shadow var(--transition-normal);
}

.top-control-btn:hover {
  color: var(--brand);
  border-color: var(--brand);
  background: var(--bg-card);
  box-shadow: var(--shadow-md);
}

.top-control-btn svg {
  flex-shrink: 0;
  display: block;
}

/* Theme icon visibility — CSS-driven via [data-theme] attribute on <html>. */
/* The svg qualifier gives this rule the weight of `.top-control-btn svg` above, which comes first. */
svg.theme-icon-dark { display: none; }
[data-theme="dark"] .theme-icon-dark { display: block; }
[data-theme="dark"] .theme-icon-light { display: none; }

/* --- Login Responsive --- */
@media (max-width: 600px) {
  .login-card {
    padding: var(--space-7) var(--space-5);
  }

  .login-info-cards {
    flex-direction: column;
  }

  .login-bottom-links {
    flex-wrap: wrap;
    justify-content: center;
  }
}