/*
 * BrickDb component styles (aiero-design-system.md §8) - LEGACY, TEMPORARY
 * ----------------------------------------------------------------------------
 * Shared component rules for the pages the AIERO phases have not restyled yet. Part of
 * the legacy layer (LegacyStylesheetManifest): it only shrinks, and phase 7 deletes it.
 * The look guards that pinned these blocks (the class census, the cascade order, the
 * glass budget, the bottom-bar clearance) were retired with the old look.
 *
 * Rules that apply throughout, per the brief:
 *   - Authored at 360px first; every widening step is a min-width media query
 *     (600 / 905 / 1240 / 1440, matching aiero-design-system.md §8).
 *   - Every interactive target is >=44x44px.
 *   - Nothing requires :hover to reveal an action — hover-only refinements are
 *     wrapped in @media (hover: hover) and (pointer: fine) so touch/keyboard
 *     users never lose an affordance.
 *   - No page scrolls horizontally at any width; wide content scrolls inside
 *     its own container.
 *   - Class names are prefixed bd-, BEM-ish (block__element--modifier).
 * ----------------------------------------------------------------------------
 */

/* =========================================================================
   GlassSurface (§2.4.2) — ported from OutaStory's own GlassSurface.razor /
   ui-v2-worlds.css, retinted to BrickDb's own palette. Chrome only: TopBar,
   sheets, modals, overlay surfaces. Never a card, list
   row, or anything inside a scrolling region — see Components/GlassSurface.razor and
   aiero-design-system.md §8.

   background/border/box-shadow are set UNCONDITIONALLY; only backdrop-filter (the blur
   itself) is wrapped in @supports, with the -webkit- prefix alongside. That means the
   un-blurred state is never a different, separately-verified "fallback" colour — it's
   the same translucent fill, just without blur, which aiero-design-system.md §8's proof
   already covers because that proof never depended on blur being present. This is what
   keeps GlassSurface correct on older Android WebView (pre-Chromium "blink"
   backdrop-filter support, still present on some Play/Amazon/Samsung-shipped devices —
   see the store matrix) with zero extra work: the @supports block just never fires there.
   ========================================================================= */

.bd-glass {
  background: var(--bd-color-glass-bg);
  border: 1px solid var(--bd-color-glass-border);
  box-shadow: var(--bd-shadow-2), var(--bd-color-glass-highlight);
}

.bd-glass--strong {
  background: var(--bd-color-glass-bg-strong);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .bd-glass,
  .bd-glass--strong {
    backdrop-filter: blur(var(--bd-glass-blur));
    -webkit-backdrop-filter: blur(var(--bd-glass-blur));
  }
}

/* Three independent user preferences collapse every glass surface to the same opaque,
   already-verified fill (--bd-color-surface-raised) — aiero-design-system.md §8/§9:
   prefers-reduced-transparency (a user who finds translucency hard to read), prefers-
   contrast: more (the concrete mechanism OutaStory's own token comment notes high-
   contrast mode opts out of), and reduced motion is handled separately below since
   transparency and motion are different preferences. */
@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  .bd-glass,
  .bd-glass--strong {
    background: var(--bd-color-surface-raised);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* prefers-reduced-motion follows the existing rule elsewhere in this file: a sheet's or
   modal's appear/disappear blur/opacity TRANSITION is skipped or capped at
   --bd-duration-instant; the resting glass state itself (this block) is unaffected —
   motion and transparency are separate preferences, gated by separate media queries. */
@media (prefers-reduced-motion: reduce) {
  .bd-glass,
  .bd-glass--strong {
    transition: none;
  }
}

/* =========================================================================
   Shared primitives — buttons
   Used by EmptyState, ConfirmSheet, TopBar and SearchField actions.
   ========================================================================= */

.bd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--bd-space-2);
  min-height: 44px;
  min-width: 44px;
  padding: 0 var(--bd-space-5);
  border-radius: var(--bd-radius-pill);
  border: none;
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-body-sm-size);
  line-height: 1;
  white-space: nowrap;
  transition: background-color var(--bd-duration-short) var(--bd-ease-standard),
              color var(--bd-duration-short) var(--bd-ease-standard),
              border-color var(--bd-duration-short) var(--bd-ease-standard);
}

.bd-btn:disabled {
  opacity: 0.5;
  pointer-events: none;
}

.bd-btn--primary {
  background: var(--bd-color-primary);
  color: var(--bd-color-on-primary); /* white since 2026-09-04 — see bd-compat.css §2.3 */
}

.bd-btn--primary:active {
  background: var(--bd-color-primary-dark);
}

@media (hover: hover) and (pointer: fine) {
  .bd-btn--primary:hover {
    background: var(--bd-color-primary-mid);
  }
}

.bd-btn--secondary {
  background: transparent;
  color: var(--bd-color-on-surface);
  border: 1px solid var(--bd-color-border-strong);
}

.bd-btn--secondary:active {
  background: var(--bd-color-surface);
}

a.bd-btn {
  text-decoration: none;
}

:root a.bd-btn--primary {
  color: var(--bd-color-on-primary);
}

:root a.bd-btn--secondary {
  color: var(--bd-color-on-surface);
}

.bd-btn--danger-text {
  background: transparent;
  color: var(--bd-color-danger);
  padding-inline: var(--bd-space-3);
  text-decoration: underline;
  text-decoration-thickness: max(1px, 0.08em);
}

.bd-btn--icon {
  min-width: 44px;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: var(--bd-radius-pill);
  background: transparent;
  color: var(--bd-color-on-surface);
}

.bd-btn--icon:active {
  background: var(--bd-color-surface);
}

.bd-btn__icon-svg {
  width: 22px;
  height: 22px;
  flex: none;
}

/* =========================================================================
   TopBar — sticky header (§5). Chrome, rendered through
   <GlassSurface Class="bd-top-bar"> — see the note on BottomNav above; this
   block owns layout only, never background/box-shadow.
   ========================================================================= */

.bd-top-bar {
  position: sticky;
  top: var(--site-header-height); /* below the fixed header once scrolled */
  z-index: var(--bd-z-sticky-header);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bd-space-3);
  min-height: 56px;
  padding: var(--bd-space-2) var(--bd-space-4);
  padding-top: calc(var(--bd-space-2) + var(--bd-safe-area-top));
  border-bottom: 1px solid var(--bd-color-border);
}

.bd-top-bar__title {
  font-family: var(--bd-font-display);
  font-weight: 600;
  font-size: var(--bd-type-headline-size);
  line-height: var(--bd-type-headline-line);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bd-top-bar__actions {
  display: flex;
  align-items: center;
  gap: var(--bd-space-1);
  flex: none;
  /* Caller supplies a bounded action fragment. */
}

/* =========================================================================
   Card grid / dense list shells shared by SetCard, PartTile.
   Browse surfaces use the card grid (2 cols at sm, 2-3 at md — §4.1);
   Collection surfaces stay single-column (density beats grid — §1.4).
   ========================================================================= */

.bd-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--bd-space-4);
}

@media (min-width: 600px) {
  .bd-card-grid {
    /* minmax(0, 1fr), not a bare 1fr: a bare 1fr track's minimum width is its content's
       intrinsic size, so a set/part/minifig title long enough to be one unbroken run of
       characters would widen the whole grid rather than truncate inside its card -
       BrickDb.App.Shared.Tests.Design.NoHorizontalScrollSourceGuardTests. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 905px) {
  .bd-card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--bd-space-5);
  }
}

.bd-list {
  display: flex;
  flex-direction: column;
}

.bd-list .bd-part-tile:first-child {
  border-top-left-radius: var(--bd-radius-md);
  border-top-right-radius: var(--bd-radius-md);
}

.bd-list .bd-part-tile:last-child {
  border-bottom-left-radius: var(--bd-radius-md);
  border-bottom-right-radius: var(--bd-radius-md);
  border-bottom: none;
}

/* =========================================================================
   EmptyState (§5) — zero-result search, empty collection, missing-image
   slots (lighter inline variant).
   ========================================================================= */

.bd-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--bd-space-4);
  padding: var(--bd-space-8) var(--bd-space-5);
}

/* The illustration is the one large graphic on an otherwise empty screen, and a grey
   one makes an empty collection read as a broken collection. It takes the brand colour,
   resolved per theme exactly the way app.css resolves link colour (base primary in
   light, primary-light in dark — the base ramp is calibrated for fills, not for text
   or line-art on a dark ground, bd-compat.css §2.3), on a tinted disc so it reads as a
   deliberate illustration rather than a stray icon. Non-text, ≥3:1 against the section
   surface in both themes. */
.bd-empty-state__icon {
  width: 88px;
  height: 88px;
  padding: var(--bd-space-3);
  border-radius: var(--bd-radius-pill);
  background: var(--bd-color-section-surface);
  color: var(--bd-color-primary);
}

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

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

.bd-empty-state__title,
.bd-confirm-sheet__title,
.bd-alert__title {
  font-family: var(--bd-font-display);
  font-weight: 600;
  font-size: var(--bd-type-title-size);
  line-height: var(--bd-type-title-line);
}

.bd-empty-state__message,
.bd-confirm-sheet__message,
.bd-alert__message {
  font-size: var(--bd-type-body-size);
  line-height: var(--bd-type-body-line);
}

.bd-empty-state__message,
.bd-confirm-sheet__message {
  color: var(--bd-color-muted);
}

.bd-empty-state__message {
  max-width: 40ch;
}

/* Lighter inline variant — used for missing-image slots inside a tile/card
   rather than a full empty screen (aiero-design-system.md §10.1). */
.bd-empty-state--inline {
  padding: var(--bd-space-3);
  gap: var(--bd-space-2);
  background: var(--bd-color-section-surface);
  border-radius: inherit;
  height: 100%;
  justify-content: center;
}

.bd-empty-state--inline .bd-empty-state__icon {
  width: 32px;
  height: 32px;
  padding: 0;
  background: none;
}

.bd-empty-state--inline .bd-empty-state__message {
  font-size: var(--bd-type-caption-size);
  line-height: var(--bd-type-caption-line);
}

/* =========================================================================
   ConfirmSheet (§5) — bottom sheet for destructive/irreversible actions.
   Primary button is the SAFE action; the destructive action is secondary,
   text-styled, in --bd-color-danger — never the other way round.

   The spec doesn't call out a >=sm layout for ConfirmSheet the way it does
   for FilterSheet; a full-width bottom sheet stretched across a 1440px
   viewport reads broken, so this extends the same "sheet becomes a centred
   surface once there's room" idea FilterSheet already uses, capping the
   width and rounding all four corners from `sm` up. See the report.
   ========================================================================= */

.bd-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--bd-z-scrim);
  background: var(--bd-color-scrim);
}

.bd-confirm-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--bd-z-modal);
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-4);
  width: 100%;
  padding: var(--bd-space-3) var(--bd-space-5)
           calc(var(--bd-space-5) + var(--bd-safe-area-bottom));
  border-radius: var(--bd-radius-xl) var(--bd-radius-xl) 0 0;
  background: var(--bd-color-surface-overlay);
  box-shadow: var(--bd-shadow-4);
  animation: bd-sheet-in var(--bd-duration-medium) var(--bd-ease-emphasized);
}

.bd-confirm-sheet__handle {
  align-self: center;
  width: 36px;
  height: 4px;
  border-radius: var(--bd-radius-pill);
  background: var(--bd-color-border-strong);
}

.bd-confirm-sheet__actions {
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-2);
}

.bd-confirm-sheet__actions .bd-btn {
  width: 100%;
}

@media (min-width: 600px) {
  .bd-confirm-sheet {
    left: 50%;
    right: auto;
    bottom: var(--bd-space-6);
    transform: translateX(-50%);
    width: min(420px, calc(100% - var(--bd-space-6) * 2));
    border-radius: var(--bd-radius-xl);
    padding-bottom: var(--bd-space-5);
  }
}

@media (prefers-reduced-motion: reduce) {
  .bd-confirm-sheet {
    animation: bd-toast-in-reduced var(--bd-duration-instant) linear;
  }
}

/* =========================================================================
   Form controls — text input, select, textarea, field label/hint, toggle
   chip, disclosure, alert banner. The v1 component set (§5) has no entry
   for any of these: everything that existed before this pass was
   read-only display (SetCard, PartTile, ConditionBadge...). The condition
   editor and the add-to-collection form are the first real forms in the
   app, so this is new rather than reused — flagged per the brief. Built
   from the same tokens/rules as everything above (360px-first, >=44px
   targets, no hover-only affordance, visible focus via app.css).
   ========================================================================= */

.bd-field {
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-1);
}

.bd-field__label {
  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);
  color: var(--bd-color-on-surface);
}

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

.bd-input,
.bd-select,
.bd-textarea {
  width: 100%;
  min-height: 44px;
  padding: var(--bd-space-2) var(--bd-space-3);
  border-radius: var(--bd-radius-md);
  border: 1px solid var(--bd-color-border);
  background: var(--bd-color-surface-raised);
  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);
}

.bd-textarea {
  min-height: 88px;
  resize: vertical;
}

.bd-input:focus,
.bd-select:focus,
.bd-textarea:focus {
  outline: none; /* the visible focus ring below replaces it, per app.css */
}

.bd-input:focus-visible,
.bd-select:focus-visible,
.bd-textarea:focus-visible {
  border-color: var(--bd-color-focus-ring);
}

.bd-form-grid {
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-4);
}

@media (min-width: 600px) {
  .bd-form-grid--cols-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

.bd-checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--bd-space-2);
  min-height: 44px;
}

.bd-checkbox-row input[type="checkbox"] {
  width: 22px;
  height: 22px;
  flex: none;
  accent-color: var(--bd-color-primary);
}

/* Multi-select toggle chips — used for ConditionFlag, which is an open,
   additive set (domain-model.md §4.7): a wrapped row of tappable pills
   beats a scrolling checkbox list at this cardinality. */
.bd-toggle-chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bd-space-2);
}

.bd-toggle-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--bd-space-4);
  border-radius: var(--bd-radius-pill);
  border: 1px solid var(--bd-color-border-strong);
  background: var(--bd-color-surface-raised);
  color: var(--bd-color-on-surface);
  font-family: var(--bd-font-body);
  font-weight: 500;
  font-size: var(--bd-type-body-sm-size);
}

/* aria-current is the <a> spelling of aria-pressed, for a chip group made of links
   (the support queue filter, #859). One declaration, not a second copy. */
.bd-toggle-chip[aria-pressed="true"],
.bd-toggle-chip[aria-current="page"] {
  background: var(--bd-color-primary);
  border-color: var(--bd-color-primary);
  color: var(--bd-color-on-primary);
  font-weight: 600;
}

/* Progressive disclosure — a native <details>/<summary> pair so the
   expand/collapse affordance is keyboard- and screen-reader-operable with
   no script. Used to tuck the seven-axis condition editor's less-common
   axes below the fast path (the old design brief: "must not feel like a
   tax form"). */
.bd-disclosure {
  border: 1px solid var(--bd-color-border);
  border-radius: var(--bd-radius-md);
  background: var(--bd-color-section-surface);
  overflow: hidden;
}

.bd-disclosure__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--bd-space-2);
  min-height: 44px;
  /* The 4px inset is the accent rule below, not decoration for its own sake: it is what
     marks the row as a section header rather than another form field, at a glance and
     without reading it. */
  padding: var(--bd-space-3) var(--bd-space-4) var(--bd-space-3) var(--bd-space-3);
  border-left: 4px solid var(--bd-color-primary);
  cursor: pointer;
  list-style: none;
  font-family: var(--bd-font-body);
  font-weight: 600;
  font-size: var(--bd-type-body-size);
}

.bd-disclosure__summary::-webkit-details-marker {
  display: none;
}

.bd-disclosure__summary-icon {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--bd-color-muted);
  transition: transform var(--bd-duration-short) var(--bd-ease-standard);
}

.bd-disclosure[open] .bd-disclosure__summary-icon {
  transform: rotate(180deg);
}

.bd-disclosure__body {
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-4);
  padding: 0 var(--bd-space-4) var(--bd-space-4);
  border-top: 1px solid var(--bd-color-border);
  padding-top: var(--bd-space-4);
}

/* Alert banner — inline error states ("what went wrong", never "something
   went wrong"), with an optional retry action. */
.bd-alert {
  display: flex;
  flex-direction: column;
  gap: var(--bd-space-3);
  padding: var(--bd-space-4);
  border-radius: var(--bd-radius-md);
  background: var(--bd-color-danger-surface);
}

.bd-alert__title {
  color: var(--bd-color-on-surface);
}

.bd-alert__message {
  color: var(--bd-color-on-surface);
}

.bd-alert__actions {
  display: flex;
  gap: var(--bd-space-2);
}

/* ---------------------------- Tables ---------------------------------- */

.bd-table-scroll {
  overflow-x: auto;
  position: relative;
  /* Without this the flex/grid parent sizes to the table's intrinsic width
     and the overflow lands on the page instead of in here. */
  min-width: 0;
  max-width: 100%;
  margin: var(--bd-space-3) 0;
}

.bd-table {
  border-collapse: collapse;
  /* Not width:100% — a narrow viewport must be allowed to scroll the table
     rather than crush its columns into unreadable slivers. */
  min-width: 100%;
  font-family: var(--bd-font-body);
  font-size: var(--bd-type-body-sm-size);
  line-height: var(--bd-type-body-sm-line);
  color: var(--bd-color-on-surface);
}

.bd-table th,
.bd-table td {
  text-align: left;
  padding: var(--bd-space-2) var(--bd-space-3);
  border-bottom: 1px solid var(--bd-color-border);
  vertical-align: top;
}

.bd-table th {
  font-weight: 600;
  white-space: nowrap;
}

/* ABOVE THE BOTTOM BAR, NOT BEHIND IT: a toast clears whatever chrome is on screen. Below
   the 1100px header breakpoint that is the bar's 64px (--site-bottom-bar-height) plus the
   inset; above it the bar is gone and so is the offset. Guard: BottomBarClearanceTests. */
.bd-toast-region {
  position: fixed;
  right: var(--bd-space-4);
  bottom: calc(var(--bd-space-4) + 64px + var(--bd-safe-area-bottom));
  left: var(--bd-space-4);
  z-index: var(--bd-z-toast);
  pointer-events: none;
}

@media (min-width: 1100px) {
  .bd-toast-region {
    bottom: calc(var(--bd-space-4) + var(--bd-safe-area-bottom));
  }
}

.bd-toast {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--bd-space-2);
  max-width: 36rem;
  margin-inline: auto;
  padding: var(--bd-space-3);
  border: 1px solid var(--bd-color-border-strong);
  border-radius: var(--bd-radius-lg);
  background: var(--bd-color-surface-overlay);
  box-shadow: var(--bd-shadow-3);
  pointer-events: auto;
}

.bd-toast__severity {
  font-size: var(--bd-type-caption-size);
  font-weight: 700;
}

.bd-toast--success .bd-toast__severity { color: var(--bd-color-success); }
.bd-toast--warning .bd-toast__severity { color: var(--bd-color-warning); }
.bd-toast--error .bd-toast__severity { color: var(--bd-color-danger); }

/* min-width: 0 is the shell's own rule applied here — without it a long
   e-mail address refuses to shrink in a flex row and pushes the page
   sideways at 360px. */
[data-account-identity] > .bd-stack {
    min-width: 0;
    overflow-wrap: anywhere;
}


@keyframes bd-sheet-in {
  from { opacity: 0; transform: translateY(24px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (min-width: 600px) {
  @keyframes bd-sheet-in {
    from { opacity: 0; transform: translate(-50%, 24px); }
    to { opacity: 1; transform: translate(-50%, 0); }
  }}
