/* FMeter design base on Fluent 2 tokens (vendor/fluent-tokens-*-themed.css).
   docs/DESIGN.md is the guide. Owner: lead. Layers, all linked from base.html:
     fluent.css      base: theme aliases (--fm-*), reset, type ramp, icons, native controls
     shell.css       app frame: suite header, nav pane, tenant header, view-as, anonymous pages
     components.css  shared components: page header, command bar, cards, data grid, status,
                     side pane, charts, empty states, chips, tabs/segmented
     legacy.css      the old page styles, only inside <div class="page legacy"> (unconverted pages)
     overview.css / meters.css / usage.css / admin-lists.css / tenant.css / auth.css
                     one file per screen, owned by that screen
   CSP (style-src 'self'): no inline styles anywhere; everything lives in these files. */

/* ---- Theme aliases (tokens only; re-pointed per theme) ------------------- */
:root {
  --fm-suite-bg: var(--colorNeutralBackgroundInverted);
  --fm-suite-fg: var(--colorNeutralForegroundInverted);
  --fm-suite-fg2: var(--colorNeutralForegroundInverted2);
  --fm-suite-hover: var(--colorNeutralBackgroundInvertedHover);
  --fm-suite-pressed: var(--colorNeutralBackgroundInvertedPressed);
  --fm-suite-stroke: var(--colorNeutralStrokeAlpha2);
  --fm-canvas: var(--colorNeutralBackground3);
  --fm-pane: var(--colorNeutralBackground1);
  --fm-pane-stroke: var(--colorNeutralStroke2);
  --fm-card: var(--colorNeutralBackground1);
  --fm-card-stroke: transparent;
  --fm-card-shadow: var(--shadow2);
  --fm-row-stroke: var(--colorNeutralStroke2);
  /* Medium identity: one tint per medium */
  --fm-heat: var(--colorPaletteDarkOrangeBorderActive);
  --fm-cold: var(--colorPaletteTealBorderActive);
  --fm-hot: var(--colorPaletteBerryBorderActive);
  --fm-el: var(--colorPaletteMarigoldForeground1);
  --fm-heat-bg: color-mix(in srgb, var(--fm-heat) 12%, transparent);
  --fm-cold-bg: color-mix(in srgb, var(--fm-cold) 12%, transparent);
  --fm-hot-bg: color-mix(in srgb, var(--fm-hot) 12%, transparent);
  --fm-el-bg: color-mix(in srgb, var(--fm-el) 14%, transparent);
  /* Charts (charts.js reads these) */
  --fm-prev: var(--colorNeutralStroke1);
  --fm-prev-line: var(--colorNeutralStrokeAccessible);
  --fm-ret: var(--colorPaletteBlueBorderActive);
  --fm-grid: var(--colorNeutralStroke2);
  --fm-band-bad: color-mix(in srgb, var(--colorStatusDangerBackground3) 10%, transparent);
  --fm-flag: var(--colorStatusWarningBorderActive);
  --fm-axis: var(--colorNeutralForeground3);
  --fm-axis-strong: var(--colorNeutralForeground2);
  --fm-nav-w: 240px;
  --fm-danger-fg: var(--colorStatusDangerForeground1);
  --fm-count-bg: var(--colorNeutralBackground5);
}
/* Dark: frame (header + nav) Background2, canvas Background3, cards Background1, no card
   shadow, Stroke2/3 hairlines. Same block twice: OS dark unless data-theme="light", and
   data-theme="dark" (docs/DESIGN.md "Theme"). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --fm-suite-bg: var(--colorNeutralBackground2);
    --fm-suite-fg: var(--colorNeutralForeground1);
    --fm-suite-fg2: var(--colorNeutralForeground2);
    --fm-suite-hover: var(--colorSubtleBackgroundHover);
    --fm-suite-pressed: var(--colorSubtleBackgroundPressed);
    --fm-suite-stroke: var(--colorNeutralStroke2);
    --fm-pane: var(--colorNeutralBackground2);
    --fm-count-bg: var(--colorNeutralBackground6);
    --fm-card-shadow: none;
    --fm-row-stroke: var(--colorNeutralStroke3);
    --fm-grid: var(--colorNeutralStroke3);
    --fm-danger-fg: var(--colorStatusDangerForeground3);
  }
}
:root[data-theme="dark"] {
  --fm-suite-bg: var(--colorNeutralBackground2);
  --fm-suite-fg: var(--colorNeutralForeground1);
  --fm-suite-fg2: var(--colorNeutralForeground2);
  --fm-suite-hover: var(--colorSubtleBackgroundHover);
  --fm-suite-pressed: var(--colorSubtleBackgroundPressed);
  --fm-suite-stroke: var(--colorNeutralStroke2);
  --fm-pane: var(--colorNeutralBackground2);
  --fm-count-bg: var(--colorNeutralBackground6);
  --fm-card-shadow: none;
  --fm-row-stroke: var(--colorNeutralStroke3);
  --fm-grid: var(--colorNeutralStroke3);
  --fm-danger-fg: var(--colorStatusDangerForeground3);
}

/* ---- Reset and base ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  background: var(--fm-canvas);
  color: var(--colorNeutralForeground1);
  font-family: var(--fontFamilyBase);
  font-size: var(--fontSizeBase300);
  line-height: var(--lineHeightBase300);
  font-weight: var(--fontWeightRegular);
  -webkit-font-smoothing: antialiased;
}
/* Custom elements render their light DOM as plain text until the bundle defines them. */
:not(:defined) { visibility: hidden; }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, form, fieldset { margin: 0; }
h1, h2, h3, h4 { font-size: inherit; line-height: inherit; font-weight: var(--fontWeightSemibold); }
ul, ol { padding: 0; list-style: none; }
fieldset { padding: 0; border: 0; min-width: 0; }
b, strong { font-weight: var(--fontWeightSemibold); }
a { color: var(--colorBrandForegroundLink); text-decoration: none; }
a:hover { color: var(--colorBrandForegroundLinkHover); text-decoration: underline; }
a:active { color: var(--colorBrandForegroundLinkPressed); }
button { font: inherit; color: inherit; }
small { font-size: var(--fontSizeBase200); line-height: var(--lineHeightBase200); }
code, kbd, pre, samp { font-family: var(--fontFamilyMonospace); font-size: var(--fontSizeBase200); }
/* Fluent 2 focus: 2px colorStrokeFocus2 outside a 1px colorStrokeFocus1 inner ring */
:focus-visible {
  outline: 2px solid var(--colorStrokeFocus2); outline-offset: 1px;
  box-shadow: 0 0 0 1px var(--colorStrokeFocus1); border-radius: var(--borderRadiusMedium);
}
#main:focus, #main:focus-visible, #flash:focus { outline: none; box-shadow: none; }

/* ---- Utilities ---------------------------------------------------------- */
.sr-only, .visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.num { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--fontFamilyMonospace); font-size: var(--fontSizeBase200); color: var(--colorNeutralForeground3); letter-spacing: 0; }
.muted { color: var(--colorNeutralForeground3); }
.unit { color: var(--colorNeutralForeground3); font-weight: var(--fontWeightRegular); }
.dot { color: var(--colorNeutralForeground4); }
.overflow-auto, .table-wrap { overflow-x: auto; }
/* .only-m-flex is doubled to out-rank component display rules such as .card-foot. */
.only-sm, .only-m-flex.only-m-flex, .only-m-inline { display: none; }
@media (max-width: 767px) {
  .hide-sm { display: none !important; }
  .only-sm { display: inline; }
  .only-m-flex.only-m-flex { display: flex; }
  .only-m-inline { display: inline-flex; }
}

/* Icons: {% call ui::icon("fire_20_regular") %} renders
   <svg class="i" aria-hidden="true" focusable="false"><use href="/static/icons/fluent.svg#fire_20_regular"></use></svg> */
.i { width: 20px; height: 20px; flex: none; fill: currentColor; display: inline-block; vertical-align: middle; }
.i12 { width: 12px; height: 12px; }
.i16 { width: 16px; height: 16px; }
.i24 { width: 24px; height: 24px; }
.i32 { width: 32px; height: 32px; }

/* Type ramp (Fluent 2 web): Title3, Subtitle2, Body1/Body1Strong, Caption1. Semibold, never Bold. */
.t-title3 { font-size: var(--fontSizeBase600); line-height: var(--lineHeightBase600); font-weight: var(--fontWeightSemibold); }
.t-subtitle2 { font-size: var(--fontSizeBase400); line-height: var(--lineHeightBase400); font-weight: var(--fontWeightSemibold); }
.t-body1s { font-weight: var(--fontWeightSemibold); }
.t-caption1 { font-size: var(--fontSizeBase200); line-height: var(--lineHeightBase200); color: var(--colorNeutralForeground3); }
.t-caption1s { font-size: var(--fontSizeBase200); line-height: var(--lineHeightBase200); font-weight: var(--fontWeightSemibold); color: var(--colorNeutralForeground2); }

/* Skip link */
.skip-link {
  position: absolute; left: 8px; top: -48px; z-index: 100;
  background: var(--colorNeutralBackground1); color: var(--colorBrandForegroundLink);
  padding: 8px 12px; border-radius: var(--borderRadiusMedium); box-shadow: var(--shadow8);
}
.skip-link:focus { top: 8px; }

/* ---- Forms (docs/FLUENT.md "Forms") ------------------------------------- */
/* One field per row: label (in the Fluent control's default slot, or a .field-label for
   native controls and fluent-dropdown), control, then hint or error. */
.field { display: flex; flex-direction: column; align-items: stretch; gap: var(--spacingVerticalXXS); max-width: 32rem; }
.field > fluent-text-input, .field > fluent-textarea, .field > fluent-dropdown,
.field > input, .field > select, .field > textarea { width: 100%; max-width: 100%; }
.field-label, .native-label {
  display: block; color: var(--colorNeutralForeground1);
  font-size: var(--fontSizeBase300); line-height: var(--lineHeightBase300); font-weight: var(--fontWeightRegular);
}
.field-hint { display: block; color: var(--colorNeutralForeground3); }
.field-error { display: block; color: var(--colorPaletteRedForeground1); }
.form-error { color: var(--colorPaletteRedForeground1); font-weight: var(--fontWeightSemibold); }
/* Compact forms in a row (filters, table rows): fields side by side, bottom-aligned. */
form.inline, .form-row {
  display: inline-flex; flex-wrap: wrap; align-items: flex-end;
  gap: var(--spacingVerticalS) var(--spacingHorizontalS); vertical-align: bottom;
}
form.inline > .field, .form-row > .field { margin: 0; max-width: none; }
form.inline .field-error, form.inline .field-hint { white-space: normal; }
.inline-form { display: inline-flex; align-items: center; gap: var(--spacingHorizontalXS); margin: 0; }

/* Native controls without a Fluent component (password, date, file, select, search)
   look like fluent-text-input: 32px, 4px corners, accessible bottom stroke. */
input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]),
select, textarea {
  min-height: 32px; max-width: 100%; padding: 0 var(--spacingHorizontalM);
  font: inherit; color: var(--colorNeutralForeground1);
  background: var(--colorNeutralBackground1);
  border: 1px solid var(--colorNeutralStroke1); border-bottom-color: var(--colorNeutralStrokeAccessible);
  border-radius: var(--borderRadiusMedium);
}
textarea { padding-block: var(--spacingVerticalXS); }
input[type="file"] { padding: var(--spacingVerticalXS) var(--spacingHorizontalS); }
input[type="file"]::file-selector-button {
  margin-inline-end: var(--spacingHorizontalS); padding: var(--spacingVerticalXXS) var(--spacingHorizontalM);
  font: inherit; font-weight: var(--fontWeightSemibold); color: var(--colorNeutralForeground1);
  background: var(--colorNeutralBackground1); border: 1px solid var(--colorNeutralStroke1);
  border-radius: var(--borderRadiusMedium); cursor: pointer;
}
input:not([type="hidden"]):hover, select:hover, textarea:hover {
  border-color: var(--colorNeutralStroke1Hover); border-bottom-color: var(--colorNeutralStrokeAccessibleHover);
}
input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none; box-shadow: none; border-bottom: 2px solid var(--colorCompoundBrandStroke);
}
/* Same specificity as the base rule above, later in the file, so the red stroke wins. */
input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"])[aria-invalid="true"],
select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--colorPaletteRedBorder2); border-bottom-color: var(--colorPaletteRedBorder2);
}
/* Fluent text controls: red stroke for server-side errors (aria-invalid on the host). */
fluent-text-input[aria-invalid="true"]::part(root), fluent-textarea[aria-invalid="true"]::part(root) { border-color: var(--colorPaletteRedBorder2); }
/* fluent-dropdown is 34px tall, native date inputs 32px: equalise in filter rows. */
.form-row input[type="date"], form.inline input[type="date"] { height: 34px; }

/* ---- Buttons ------------------------------------------------------------ */
/* Destructive actions (data-confirm): outline in red, readable in both themes. */
fluent-button.danger, fluent-anchor-button.danger { color: var(--colorStatusDangerForeground3); border-color: var(--colorStatusDangerBorder2); }
fluent-button.danger:hover, fluent-anchor-button.danger:hover {
  color: var(--colorStatusDangerForeground3); border-color: var(--colorStatusDangerForeground3); background-color: var(--colorStatusDangerBackground1);
}
fluent-button.danger:active { background-color: var(--colorStatusDangerBackground1); }
/* htmx request running (forms.js section 4). */
fluent-button[aria-busy="true"], button[aria-busy="true"] { cursor: progress; opacity: 0.7; }
/* htmx request indicators (includeIndicatorStyles:false in base.html, CSP). */
.htmx-indicator { opacity: 0; transition: opacity 200ms ease-in; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; animation: none !important; } }
