/*
 * BrickDb base layer
 * ----------------------------------------------------------------------------
 * Consumes tokens.css. Body defaults, the type scale applied to headings/body
 * text, link/focus styles, the .bd-page shell, and shared utility classes.
 * Declares Outfit (display) and Inter (body) with real fallback stacks — see the
 * report for the pairing rationale. Both are SELF-HOSTED from ../fonts/, never
 * from Google Fonts: a CDN @import makes the visitor's browser hand its IP
 * address, User-Agent and Referer to a third party before any consent, which is
 * the fact pattern LG München I, 3 O 17493/20 awarded damages for. The privacy
 * policy claims in as many words that the page contacts no third-party server,
 * so this file may never reference an external host again. Guard:
 * BrickDb.App.Shared.Tests.ExternalAssetReferenceTests.
 *
 * Author at 360px; every override below 905px uses min-width only (design-
 * system.md §1.1 / §4).
 * ----------------------------------------------------------------------------
 */

/* ================= Self-hosted web fonts =================
   One variable file per family rather than one static file per weight: Outfit's
   three weights (500/600/700) cost 40.8 kB as statics against 32.3 kB variable,
   Inter's three (400/500/600) cost 71 kB against 48.3 kB — smaller, and two
   requests instead of six. Both are SIL OFL 1.1, so redistributing them is
   permitted; the licence text ships alongside them in wwwroot/fonts/.

   The weight ranges below are the ones the design system actually uses, not the
   axis's full 100–900: a range that lies would let a stray font-weight: 900 be
   synthesised silently. `font-display: swap` keeps text visible while the file
   loads — the same behaviour the old &display=swap parameter asked for.

   ../fonts/ resolves relative to THIS stylesheet, not to the page, so the one
   path is correct for both heads: _content/BrickDb.App.Shared/css/app.css on the
   Blazor web head and the same virtual path inside the MAUI WebView. */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url('../fonts/outfit-variable.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/inter-variable.woff2') format('woff2');
}

/* ================= Responsive type-scale overrides =================
   design-system.md §3.1 gives a mobile size/line-height and a >=905px
   size/line-height per token. The mobile values live in tokens.css as the
   default; this is the single >=905px override point, redefining only the
   size/line half of the pair, per breakpoint rules in §4. */
@media (min-width: 905px) {
  :root {
    --bd-type-display-lg-size: 2.75rem;   /* 44px */
    --bd-type-display-lg-line: 3.25rem;   /* 52px */
    --bd-type-display-size: 2.125rem;     /* 34px */
    --bd-type-display-line: 2.5rem;       /* 40px */
    --bd-type-headline-size: 1.625rem;    /* 26px */
    --bd-type-headline-line: 2rem;        /* 32px */
    --bd-type-title-size: 1.25rem;        /* 20px */
    --bd-type-title-line: 1.625rem;       /* 26px */
    --bd-type-body-lg-size: 1.125rem;     /* 18px */
    --bd-type-body-lg-line: 1.625rem;     /* 26px */
    --bd-type-body-size: 1rem;            /* 16px — floor, never shrinks */
    --bd-type-body-line: 1.5rem;          /* 24px */
    --bd-type-caption-size: 0.8125rem;    /* 13px */
    --bd-type-caption-line: 1.125rem;     /* 18px */
    /* body-sm and label are fixed across all breakpoints per §3.1. */
  }
}

/* ================= Body defaults ================= */
/* The glass redesign's background is the bounded backdrop mesh (tokens.css
   --bd-color-backdrop, design-system.md §2.4.1), not a flat --bd-color-surface fill —
   glass chrome (TopBar, PrimaryNav, sheets/modals) floats over this everywhere. It's
   still an explicit token-driven background, never a browser/OS default, and every
   contrast pair verified against --bd-color-surface stays valid because the mesh never
   drops below the floor/ceiling §2.4.1 states (recompute that table if the stops move). */
body {
  background: var(--bd-color-backdrop);
  background-color: var(--bd-color-surface); /* fallback: engines without gradient layering still get the flat colour */
  color: var(--bd-color-on-surface);
  font-family: var(--bd-font-body);
  font-size: var(--bd-type-body-size);
  line-height: var(--bd-type-body-line);
  font-weight: 400;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

/* ================= Heading / text type scale =================
   The design-system doc scopes its named type tokens to specific components
   (TopBar title, SetCard title, etc.) rather than to h1-h6 directly. This is
   the extension needed to give running document content (notes, help text,
   about screens) a sane heading hierarchy built from the same tokens — see
   the report. h1/h2/h3 map onto display/headline/title as the doc's closest
   "screen-level header" / "section header" / "card & sheet title" tiers;
   h4-h6 step down through the body tiers at 600 weight since the scale has
   no dedicated sub-title tokens. */
h1,
.bd-display {
  font-family: var(--bd-font-display);
  font-weight: 700;
  font-size: var(--bd-type-display-size);
  line-height: var(--bd-type-display-line);
}

h2,
.bd-headline {
  font-family: var(--bd-font-display);
  font-weight: 600;
  font-size: var(--bd-type-headline-size);
  line-height: var(--bd-type-headline-line);
}

h3,
.bd-title {
  font-family: var(--bd-font-display);
  font-weight: 600;
  font-size: var(--bd-type-title-size);
  line-height: var(--bd-type-title-line);
}

h4 {
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-body-lg-size);
  line-height: var(--bd-type-body-lg-line);
}

h5 {
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-body-size);
  line-height: var(--bd-type-body-line);
}

h6 {
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-body-sm-size);
  line-height: var(--bd-type-body-sm-line);
}

.bd-display-lg {
  font-family: var(--bd-font-display);
  font-weight: 700;
  font-size: var(--bd-type-display-lg-size);
  line-height: var(--bd-type-display-lg-line);
}

p,
.bd-body {
  font-family: var(--bd-font-body);
  font-weight: 400;
  font-size: var(--bd-type-body-size);
  line-height: var(--bd-type-body-line);
}

.bd-body-lg {
  font-family: var(--bd-font-body);
  font-weight: 400;
  font-size: var(--bd-type-body-lg-size);
  line-height: var(--bd-type-body-lg-line);
}

.bd-body-sm {
  font-family: var(--bd-font-body);
  font-weight: 500;
  font-size: var(--bd-type-body-sm-size);
  line-height: var(--bd-type-body-sm-line);
}

/* Uppercase labels get tracking — used by ConditionBadge text, chips, small
   buttons. Never used for anything below 12px per §3. */
.bd-label {
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-label-size);
  line-height: var(--bd-type-label-line);
  letter-spacing: var(--bd-type-label-tracking);
  text-transform: uppercase;
}

.bd-caption {
  font-family: var(--bd-font-body);
  font-weight: 400;
  font-size: var(--bd-type-caption-size);
  line-height: var(--bd-type-caption-line);
  color: var(--bd-color-muted);
}

/* Running text (notes, help copy, long-form reading) stays near 65 characters
   measure regardless of the surface it sits in. */
p,
.bd-body,
.bd-body-lg,
.bd-measure {
  max-width: 65ch;
}

/* ================= Links =================
   The doc doesn't name a dedicated "link" role in its token table (§2.2);
   rather than invent a new --bd-color-* token, links reuse the existing
   primary-dark / primary-light tokens, which already carry the contrast
   properties needed (primary-dark is the "pressed/active" darkening of
   primary; primary-light is explicitly the dark-theme accent value) and
   resolve per theme with the same three-state pattern as tokens.css. */
a {
  color: var(--bd-color-primary-dark);
  text-decoration-line: underline;
  text-decoration-thickness: max(1px, 0.08em);
  text-underline-offset: 0.15em;
  transition: color var(--bd-duration-short) var(--bd-ease-standard);
}

a:hover {
  color: var(--bd-color-primary);
}

a:active {
  color: var(--bd-color-primary-dark);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) a {
    color: var(--bd-color-primary-light);
  }
}

:root[data-theme="dark"] a {
  color: var(--bd-color-primary-light);
}

/* ================= Focus visibility =================
   Every focusable element gets a clearly visible 3px outline in the theme's
   focus-ring token with a 2px offset, in addition to (not instead of) any
   platform-native focus indication. Never outline: none without this. */
:focus-visible {
  outline: 3px solid var(--bd-color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--bd-radius-sm);
}

/* An automatic, script-driven focus a user did not initiate — RouteHeadingFocus announcing a
   client-side route change to assistive tech (issue #495) — must not paint a ring. Scoped to the
   marker attribute, not to the element or the pseudo-class alone, so a GENUINE keyboard/user focus
   of the same element (there is none today, but nothing here should preclude one being added
   later, e.g. a skip link) still gets the ring the rule above draws for everything else. */
[data-auto-focused]:focus-visible {
  outline: none;
}

/* Engines without :focus-visible support (older embedded WebViews) fall back
   to :focus so focus is never invisible. */
@supports not selector(:focus-visible) {
  :focus {
    outline: 3px solid var(--bd-color-focus-ring);
    outline-offset: 2px;
  }
}

/* ================= Page shell ================= */
.bd-page {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  /* .bd-page is opaque over body, so it carries the same backdrop mesh body does —
     otherwise glass chrome (TopBar, PrimaryNav) would float over a flat fill instead of
     the mesh it's verified against (design-system.md §2.4.1). */
  background: var(--bd-color-backdrop);
  background-color: var(--bd-color-surface);
  color: var(--bd-color-on-surface);
  padding-top: var(--bd-safe-area-top);
  padding-right: var(--bd-safe-area-right);
  padding-left: var(--bd-safe-area-left);
  /* Bottom safe area is owned by AppShell/BottomNav (they sit at the very
     bottom edge and already reserve it) so .bd-page itself does not double
     up the inset; components.css adds it back on BottomNav directly. */
}

.bd-page__content {
  flex: 1 1 auto;
  width: 100%;
  padding: 0 var(--bd-space-4);
}

@media (min-width: 600px) {
  .bd-page__content {
    padding-left: var(--bd-space-6);
    padding-right: var(--bd-space-6);
  }
}

@media (min-width: 1440px) {
  .bd-page__content {
    max-width: 1280px;
    margin-inline: auto;
  }
}

/* ================= Utilities ================= */

/* Visually hides content while keeping it available to assistive tech — used
   alongside icon-only chips so a full-word description always exists in the
   accessibility tree even when an aria-label attribute is also present. */
.bd-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;
}

/* Single-line truncation with ellipsis, for list rows that must not wrap. */
.bd-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The only sanctioned way wide content may overflow: scroll inside its own
   container, never the page. Required for e.g. PhotoGallery thumbnail
   strips, wide tables, or a long FilterSheet chip row. */
.bd-scroll-x {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

/* Digits that align in columns — prices, quantities, counts. */
.bd-tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Flex row/column helpers keyed to the spacing scale, used throughout
   components.css instead of ad hoc margins. */
.bd-stack {
  display: flex;
  flex-direction: column;
}

.bd-cluster {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.bd-gap-1 { gap: var(--bd-space-1); }
.bd-gap-2 { gap: var(--bd-space-2); }
.bd-gap-3 { gap: var(--bd-space-3); }
.bd-gap-4 { gap: var(--bd-space-4); }
.bd-gap-6 { gap: var(--bd-space-6); }

/* Safe-area padding utilities, primarily for AppShell-owned chrome. */
.bd-safe-top { padding-top: var(--bd-safe-area-top); }
.bd-safe-bottom { padding-bottom: var(--bd-safe-area-bottom); }

/* sr-only skip link pattern, shown only on keyboard focus. */
.bd-skip-link {
  position: absolute;
  top: var(--bd-space-2);
  left: var(--bd-space-2);
  z-index: var(--bd-z-toast);
  transform: translateY(-200%);
  background: var(--bd-color-surface-raised);
  color: var(--bd-color-on-surface);
  padding: var(--bd-space-2) var(--bd-space-4);
  border-radius: var(--bd-radius-sm);
  box-shadow: var(--bd-shadow-3);
  transition: transform var(--bd-duration-short) var(--bd-ease-standard);
}

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