/*
  bento-grid.css — THE PRIMER
  ===========================================================================
  Structural layer ONLY. Zero color. Zero decorative styling of any kind
  (D-TPL-SHIP-02, D-TPL-NOT-01, D-TPL-TOK-03). Typography here is SHAPE only
  (scale, weight, rhythm, family stack) — never color; color is Render-layer.

  This file's content is identical in shape and intent across every BU
  Ecosystem template that ships a visual surface. It is loaded first; pull
  every render file off and the application still works, in greyscale (the
  "is it skin-related?" diagnostic — see bu-framework skill).

  Construction metaphor vocabulary used throughout this system:
    slab, bay, panel, reveal, brick, rail, transom, mullion, soffit, gate.

  Accessibility (WCAG 2.1 AA, non-negotiable):
    - Interactive controls MUST have a minimum 44px touch target (both
      dimensions). This is noted at every interactive class below.
    - Interactive controls MUST use a maximum 5px border-radius. No pill
      buttons. Cards/panels are exempt from the radius cap.
    - Do not rely on color alone to convey state; that is a Render-layer
      concern in any case, since this file carries no color.

  A spun page must read as a structured product page in greyscale — a nav
  rail, a hero region, aligned columns, styled buttons and forms — not as
  unstyled text. See docs/srs BUP-SRS-001-S07 greyscale-proof definition.
  ===========================================================================
*/

:root {
  /* Structural scale only — no color tokens live here. Spacing/sizing scale
     is expressed in rem so it respects user font-size preferences. */
  --structure-gap-xs: 0.25rem;
  --structure-gap-sm: 0.5rem;
  --structure-gap-md: 1rem;
  --structure-gap-lg: 1.5rem;
  --structure-gap-xl: 2rem;
  --structure-gap-2xl: 3rem;

  --structure-radius-max: 5px; /* Law: interactive controls, max 5px. No pill buttons. */
  --structure-radius-panel: 8px; /* Panels/cards are exempt from the interactive cap. */
  --structure-touch-min: 44px; /* Law: 44px minimum touch target on every interactive control. */

  /* z-index stack: three layers only, kept intentionally sparse. */
  --structure-z-base: 1;
  --structure-z-rail: 10;
  --structure-z-overlay: 50;

  /* Typography SHAPE scale — sizes/weights/rhythm only, never color. System
     font stack: no Google Fonts / CDN font loads anywhere (D-TPL laws). */
  --structure-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --structure-font-family-mono: ui-monospace, SFMono-Regular, "Cascadia Mono",
    "Consolas", monospace;

  --structure-text-xs: 0.75rem;
  --structure-text-sm: 0.875rem;
  --structure-text-base: 1rem;
  --structure-text-md: 1.125rem;
  --structure-text-lg: 1.375rem;
  --structure-text-xl: 1.75rem;
  --structure-text-2xl: 2.25rem;
  --structure-text-3xl: 3rem;

  --structure-leading-tight: 1.15;
  --structure-leading-base: 1.55;

  --structure-weight-normal: 400;
  --structure-weight-medium: 500;
  --structure-weight-bold: 700;

  --structure-container-max: 1200px;
}

*, *::before, *::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--structure-font-family);
  font-size: var(--structure-text-base);
  line-height: var(--structure-leading-base);
  font-weight: var(--structure-weight-normal);
}

/* -----------------------------------------------------------------------
   Typography rhythm — shape only (size, weight, spacing). Color is
   Render-layer (see render-*.css text-role tokens).
   ----------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--structure-gap-sm) 0;
  font-weight: var(--structure-weight-bold);
  line-height: var(--structure-leading-tight);
  overflow-wrap: break-word;
}

h1 { font-size: var(--structure-text-3xl); }
h2 { font-size: var(--structure-text-2xl); }
h3 { font-size: var(--structure-text-xl); }
h4 { font-size: var(--structure-text-lg); }
h5 { font-size: var(--structure-text-md); }
h6 { font-size: var(--structure-text-base); }

p {
  margin: 0 0 var(--structure-gap-md) 0;
}

p:last-child {
  margin-bottom: 0;
}

small, .bu-text-sm {
  font-size: var(--structure-text-sm);
}

ul, ol {
  margin: 0 0 var(--structure-gap-md) 0;
  padding-left: var(--structure-gap-lg);
}

a {
  font: inherit;
}

/* Form controls inherit the typeface (WT-0915-048, public leg; the admin Primer
   carries the same block). Browsers give <button>, <input>, <select> and
   <textarea> their own UA face unless told otherwise, so /inquire's Continue, all
   20 /demo switcher buttons, the report widget's Send report, its radios and its
   file input measured Arial beside system-font (or Rajdhani) labels. Inputs inside
   .bu-field already opted in further down; this is the element-level floor. FAMILY
   ONLY: size and weight stay with each component class, and specificity (0,0,1)
   means any class rule or skin face still wins. Zero colour. */
button,
input,
select,
textarea,
optgroup {
  font-family: inherit;
}

/* NEW-PUB-02 — the button inside <input type="file"> is a pseudo-element of the
   input, not a <button>, so the rule above does not reach it. The report widget's
   "Attach an image" picker rendered the UA face on every skin (Arial 13.33px, 2px
   outset border, radius 0, a 310x21 box at 1440). Same shape law as .bu-control:
   44px floor, max 5px radius, 1px solid border, the control type step. Colour
   (fill, border colour, text) is the render layer's job. */
input[type="file"]::file-selector-button {
  font-family: inherit;
  font-size: var(--structure-text-base);
  font-weight: var(--structure-weight-medium);
  min-height: var(--structure-touch-min);
  padding: var(--structure-gap-sm) var(--structure-gap-md);
  margin-inline-end: var(--structure-gap-sm);
  border-radius: var(--structure-radius-max);
  border-width: 1px;
  border-style: solid;
  cursor: pointer;
}

/* -----------------------------------------------------------------------
   .bu-slab — the outermost structural container of a page or region.
   ----------------------------------------------------------------------- */
.bu-slab {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  width: 100%;
  position: relative;
  z-index: var(--structure-z-base);
}

/* NEW-PUB-05 — short pages scrolled with nothing below: /terms at 1440 was 1184px
   of document in a 900px viewport, with a 641px empty band between the card
   (bottom y377) and the footer (y1018), so the footer was off the first screen.
   A page root is a nested .bu-slab (min-height:100vh) inside MainLayout's own
   .bu-slab (also 100vh, plus the rail offset and the footer). Opting the page root
   out lets the layout's slab own exactly one viewport. Same defect and same class
   as the admin Primer's WT-0915-046 fix. Structure only. */
.bu-fit-slab {
  min-height: 0;
}

/* -----------------------------------------------------------------------
   .bu-main — the page content region inside a layout's .bu-slab, sibling to
   .bu-rail. Plain block-level flow (NOT itself a grid) so that each page can
   supply its own .bu-bay-grid(s) without nesting a grid inside a grid — a
   grid-in-grid nesting silently collapses inner bays to a single 1-column
   width because the outer grid treats the inner root as one item.
   ----------------------------------------------------------------------- */
.bu-main {
  flex: 1;
  display: block;
  width: 100%;
}

/* -----------------------------------------------------------------------
   .bu-bay-1 .. .bu-bay-12 — a 12-column bento grid. Bays are the structural
   column-span units a .bu-panel occupies.
   ----------------------------------------------------------------------- */
.bu-bay-grid {
  display: grid;
  /* minmax(0, 1fr), not a bare 1fr: a bare 1fr's implicit minimum is
     auto (max-content of the child), which lets a single long unbroken
     word blow a column past its intended fractional width. minmax(0, 1fr)
     keeps every column genuinely equal-shareable. */
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--structure-gap-lg);
  padding: var(--structure-gap-lg) var(--structure-gap-xl);
  width: 100%;
  max-width: var(--structure-container-max);
  margin: 0 auto;
  /* R-0709-07 (owner ruling, uniform boxes): side-by-side .bu-panel cards in
     the same grid row MUST be equal height even when their content differs
     by a row — blank space inside a shorter card is fine, an offset row of
     boxes below it is the defect. align-items:start let each panel size to
     its own content, which is exactly the bug the owner flagged live on QA
     ("Choose your corner", momentum/performance-suite panels, promotion-
     philosophy vs skills panels). stretch is a general primer rule, not a
     one-section patch: every .bu-panel is already display:flex;
     flex-direction:column (see below), so a stretched grid cell simply
     gives the flex column more height to distribute — it does not distort
     panel content. */
  align-items: stretch;
}

.bu-bay-1  { grid-column: span 1; }
.bu-bay-2  { grid-column: span 2; }
.bu-bay-3  { grid-column: span 3; }
.bu-bay-4  { grid-column: span 4; }
.bu-bay-5  { grid-column: span 5; }
.bu-bay-6  { grid-column: span 6; }
.bu-bay-7  { grid-column: span 7; }
.bu-bay-8  { grid-column: span 8; }
.bu-bay-9  { grid-column: span 9; }
.bu-bay-10 { grid-column: span 10; }
.bu-bay-11 { grid-column: span 11; }
.bu-bay-12 { grid-column: span 12; }

/* Breakpoints: bays collapse to full width below tablet width so the grid
   never forces horizontal scroll on small viewports. */
@media (max-width: 768px) {
  .bu-bay-grid {
    padding: var(--structure-gap-md);
  }

  .bu-bay-1, .bu-bay-2, .bu-bay-3, .bu-bay-4, .bu-bay-5, .bu-bay-6,
  .bu-bay-7, .bu-bay-8, .bu-bay-9, .bu-bay-10, .bu-bay-11, .bu-bay-12 {
    grid-column: span 12;
  }
}

/* -----------------------------------------------------------------------
   .bu-panel — a structural card/region. Every .bu-panel MUST have a
   .bu-reveal as its first child (the panel's structural header/intro slot).
   Panels are exempt from the interactive border-radius cap.
   ----------------------------------------------------------------------- */
.bu-panel {
  display: flex;
  flex-direction: column;
  gap: var(--structure-gap-sm);
  padding: var(--structure-gap-lg);
  border-radius: var(--structure-radius-panel);
  position: relative;
  z-index: var(--structure-z-base);
  min-width: 0; /* grid item safety: don't let content force the column wider */
  /* Appearance (background, border color, elevation) is a Render-layer
     concern — see render-*.css. This file assigns no color. */
}

.bu-panel > .bu-reveal:first-child {
  display: block;
  width: 100%;
  margin-bottom: var(--structure-gap-xs);
}

/* -----------------------------------------------------------------------
   .bu-brick — the smallest structural building block (a list item, a
   stat tile, a single content atom within a panel).
   ----------------------------------------------------------------------- */
.bu-brick {
  display: flex;
  flex-direction: column;
  gap: var(--structure-gap-xs);
  padding: var(--structure-gap-sm) 0;
}

/* -----------------------------------------------------------------------
   .bu-metric — a compact stat/number tile (dashboards, value props).
   ----------------------------------------------------------------------- */
.bu-metric {
  display: flex;
  flex-direction: column;
  gap: var(--structure-gap-xs);
  padding: var(--structure-gap-md);
  border-radius: var(--structure-radius-panel);
}

.bu-metric-value {
  font-size: var(--structure-text-2xl);
  font-weight: var(--structure-weight-bold);
  line-height: var(--structure-leading-tight);
}

.bu-metric-label {
  font-size: var(--structure-text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* -----------------------------------------------------------------------
   .bu-rail — a persistent structural strip (navigation rail, header bar,
   footer bar). Sits above base content, below overlays, in the z-stack.
   Top nav shape: brand/logo left, links right, single horizontal row.
   ----------------------------------------------------------------------- */
.bu-rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--structure-gap-md);
  padding: var(--structure-gap-sm) var(--structure-gap-xl);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--structure-z-rail);
  min-height: 70px;
  width: 100%;
}

/* .bu-slab that carries a fixed .bu-rail as its first child needs top
   padding so fixed-rail content never overlaps the page's own content —
   the rail is removed from document flow by position:fixed. Applied via
   .bu-has-fixed-rail on the .bu-slab wrapper (see MainLayout). Harvested
   from the reference layout authority. */
.bu-slab.bu-has-fixed-rail {
  padding-top: 70px;
}

/* Narrow viewports: .bu-nav wraps to a second/third line below 768px, so the
   fixed rail grows well past the 70px reserved above (measured 123px at 735px
   wide, 2026-08-21) and silently overlaps the top of page content. Reserving a
   taller fixed strip cannot work — the wrapped height depends on content — so
   below the wrap breakpoint the rail returns to normal flow and occupies its
   own real height. Structure only. */
@media (max-width: 768px) {
  .bu-rail {
    position: static;
  }

  .bu-slab.bu-has-fixed-rail {
    padding-top: 0;
  }
}

/* -----------------------------------------------------------------------
   .bu-gate — an overlay/modal structural surface. Sits at the top of the
   z-stack, above rails and base content.
   ----------------------------------------------------------------------- */
.bu-gate {
  position: fixed;
  inset: 0;
  z-index: var(--structure-z-overlay);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--structure-gap-md);
}

/* -----------------------------------------------------------------------
   .bu-transom / .bu-mullion / .bu-soffit — structural dividers.
   Transom: a horizontal structural divider (above a section).
   Mullion: a vertical structural divider (between columns).
   Soffit: a structural footer/underside region of a panel or slab.
   ----------------------------------------------------------------------- */
.bu-transom {
  width: 100%;
  height: 1px;
  border: none;
  margin: var(--structure-gap-md) 0;
}

.bu-mullion {
  width: 1px;
  align-self: stretch;
  margin: 0 var(--structure-gap-md);
}

.bu-soffit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--structure-gap-sm) var(--structure-gap-md);
  min-height: var(--structure-touch-min);
}

/* -----------------------------------------------------------------------
   Navigation — brand left, link row right, horizontal single line.
   Structural only; render supplies color/hover/active appearance.
   ----------------------------------------------------------------------- */
.bu-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: var(--structure-gap-md);
}

.bu-nav-brand {
  display: inline-flex;
  align-items: center;
  font-size: var(--structure-text-md);
  font-weight: var(--structure-weight-bold);
  text-decoration: none;
  min-height: var(--structure-touch-min);
  letter-spacing: 0.02em;
}

/* Product-name suffix in the brand lockup: BELT|UP is the mark, "ONLINE" names
   the product (the company is BeltUp LLC; the app is BeltUp Online — owner
   ruling 2026-08-21). Deliberately a <small>, NOT a <span>, so the render
   layer's `.bu-nav-brand span` accent rule does not capture it — the suffix
   inherits .bu-nav-brand's own text colour in every skin, which is why it needs
   no per-skin colour rule and cannot cause partial-skin fallthrough
   (D-S07-SKIN-02). Structure only — no colour here. */
.bu-nav-brand-suffix {
  font-size: 0.62em;
  letter-spacing: 0.22em;
  margin-left: 0.5em;
  align-self: center;
}

/* .bu-nav-links sits in the CENTER of the rail (brand left, actions right) —
   flex:1 plus centered content lets it claim the middle third without a
   third explicit grid column. Harvested from the reference layout authority
   (fixed header: logo left / nav center / CTA right). */
.bu-nav-links {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: var(--structure-gap-lg);
  list-style: none;
  margin: 0;
  padding: 0;
}

.bu-nav-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--structure-touch-min);
  text-decoration: none;
  font-size: var(--structure-text-sm);
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.bu-nav-actions {
  display: flex;
  align-items: center;
  gap: var(--structure-gap-sm);
}

/* #181 (R-0915-02, REQ-MOBILENAV-001/004/006): the menu wrapper is layout-transparent on
   desktop; the toggle exists only at phone width and only once JS has marked html.bu-js
   (no-JS fallback = links stay visible and wrap, nothing is lost). */
.bu-nav-menu {
  display: contents;
}

.bu-nav-toggle {
  display: none;
}

@media (max-width: 768px) {
  .bu-nav {
    flex-wrap: wrap;
  }

  .bu-nav-menu {
    display: flex;
    flex-direction: column;
    order: 3;
    flex-basis: 100%;
    gap: var(--structure-gap-sm);
  }

  .bu-nav-links {
    flex: none;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
  }

  .bu-nav-links a {
    width: 100%;
  }

  .bu-nav-actions {
    flex-direction: column;
    align-items: stretch;
  }

  /* One 44px height for MEMBER LOG IN and the nav links on every skin (the extra
     .bu-slab outranks skins' own [data-theme] .bu-btn min-height/padding). */
  .bu-slab .bu-rail .bu-nav-actions .bu-btn {
    width: 100%;
    min-height: var(--structure-touch-min);
    padding-block: 0;
  }

  .bu-js .bu-nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    min-height: var(--structure-touch-min);
    min-width: var(--structure-touch-min);
    padding: 0 var(--structure-gap-md);
    background: transparent;
    color: var(--theme-text-main);
    border: 1px solid var(--theme-border-active);
    border-radius: var(--structure-radius-max);
    font: inherit;
    font-size: var(--structure-text-sm);
    font-weight: var(--structure-weight-bold);
    letter-spacing: 0.05em;
    cursor: pointer;
  }

  /* #181 AC1: the skins' large brand lockup (Fight Night 1.8rem + 3px tracking + suffix) wrapped
     and pushed MENU to a second row (105px at 375). Narrow-width lockup: one row, <= 80px.
     The extra .bu-nav class outranks the skins' :root[data-theme] rules; desktop is unchanged. */
  .bu-slab .bu-rail .bu-nav .bu-nav-brand {
    font-size: 1.25rem;
    letter-spacing: 1px;
    white-space: nowrap;
    flex-wrap: nowrap;
    min-width: 0;
  }

  .bu-slab .bu-rail .bu-nav .bu-nav-brand-suffix {
    font-size: 0.55em;
    letter-spacing: 0.12em;
    margin-left: 0.35em;
  }

  .bu-js .bu-nav-toggle {
    flex-shrink: 0;
  }

  .bu-js .bu-nav-toggle:focus-visible,
  .bu-js .bu-nav-menu a:focus-visible {
    outline: 2px solid var(--theme-border-active);
    outline-offset: 2px;
  }

  .bu-js .bu-nav .bu-nav-menu {
    display: none;
  }

  .bu-js .bu-nav:has(.bu-nav-toggle[aria-expanded="true"]) .bu-nav-menu {
    display: flex;
  }
}

/* -----------------------------------------------------------------------
   Hero region — eyebrow label, headline, lede, action row. Structural
   shape harvested from the reference layout authority's hero slab.
   ----------------------------------------------------------------------- */
.bu-hero {
  text-align: center;
  padding: var(--structure-gap-2xl) var(--structure-gap-xl);
}

.bu-hero-label {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.3em;
  margin-bottom: var(--structure-gap-lg);
}

.bu-hero-headline {
  font-size: clamp(2rem, 5vw, 3.75rem);
  font-weight: var(--structure-weight-bold);
  line-height: 1.05;
  letter-spacing: 0.01em;
  margin: 0 auto var(--structure-gap-lg);
  max-width: 18ch;
}

.bu-hero-lede {
  max-width: 60ch;
  margin: 0 auto var(--structure-gap-xl);
  font-size: var(--structure-text-md);
  line-height: var(--structure-leading-base);
}

.bu-hero-actions {
  display: flex;
  gap: var(--structure-gap-md);
  justify-content: center;
  flex-wrap: wrap;
}

/* -----------------------------------------------------------------------
   Interactive controls — structural rules only. Colors are Render-layer.
   Law: max 5px border-radius (no pill buttons); 44px minimum touch target.
   ----------------------------------------------------------------------- */
.bu-control {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--structure-touch-min);
  min-width: var(--structure-touch-min);
  padding: var(--structure-gap-sm) var(--structure-gap-md);
  border-radius: var(--structure-radius-max);
  border-width: 1px;
  border-style: solid;
  font-size: var(--structure-text-base);
  font-weight: var(--structure-weight-medium);
  text-decoration: none;
  line-height: 1;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.bu-control:disabled,
.bu-control[disabled] {
  cursor: not-allowed;
}

/* -----------------------------------------------------------------------
   .bu-btn / .bu-btn-secondary — inline-block button shape (BENTO-CORE
   inventory: primary solid, secondary bordered-transparent). Built on top
   of .bu-control's touch-target/radius law. Structural only.
   ----------------------------------------------------------------------- */
.bu-btn,
.bu-btn-secondary {
  /* WT-0915-047 / WT-0915-020 (public leg) — MEMBER LOG IN, the three "Get started"
     buttons, "Start the $10 trial" and Continue measured 46px beside the 44px '?'
     .bu-control on /pricing and /inquire. The line-height used to be computed as
     (touch-min - padding - 2px), which assumes a 1px border; cobalt-dark draws 2px
     top and bottom rails, so the box came out 26 + 16 + 4 = 46px. Centring the label
     in a flex box makes the height skin-independent (20 + 16 + 4 = 40, under the 44
     floor below), so every variant lands on 44 whatever rails a skin draws. Same fix
     the admin Primer carries. Fight Night restates its own 50px, unchanged. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto; /* inside a flex CTA row: hug content width, never stretch */
  width: fit-content;
  min-height: var(--structure-touch-min);
  /* The 44px law is BOTH dimensions (bento-grid.css header); .bu-control declares
     both, the button family declared height only. */
  min-width: var(--structure-touch-min);
  padding: var(--structure-gap-sm) var(--structure-gap-lg);
  border-radius: var(--structure-radius-max);
  border-width: 1px;
  border-style: solid;
  font-size: var(--structure-text-base);
  font-weight: var(--structure-weight-medium);
  text-align: center;
  text-decoration: none;
  line-height: 1.25;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}

.bu-btn:disabled,
.bu-btn-secondary:disabled {
  cursor: not-allowed;
}

/* -----------------------------------------------------------------------
   Form controls — full-width fields, stacked vertical rhythm (BENTO-CORE
   inventory: full-width fields, 0.5rem stacked gap).
   ----------------------------------------------------------------------- */
.bu-field {
  display: flex;
  flex-direction: column;
  gap: var(--structure-gap-xs);
  margin-bottom: var(--structure-gap-md);
}

.bu-field label {
  font-size: var(--structure-text-sm);
  font-weight: var(--structure-weight-medium);
}

.bu-field input[type="text"],
.bu-field input[type="email"],
.bu-field input[type="tel"],
.bu-field input[type="password"],
.bu-field input[type="number"],
.bu-field select,
.bu-field textarea,
input.bu-input,
select.bu-input,
textarea.bu-input {
  width: 100%;
  min-height: var(--structure-touch-min);
  padding: var(--structure-gap-sm) var(--structure-gap-md);
  border-radius: var(--structure-radius-max);
  border-width: 1px;
  border-style: solid;
  font-family: inherit;
  font-size: var(--structure-text-base);
}

.bu-field-row {
  display: flex;
  align-items: center;
  gap: var(--structure-gap-sm);
  min-height: var(--structure-touch-min);
}

.bu-field-row input[type="checkbox"],
.bu-field-row input[type="radio"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.bu-field-error {
  font-size: var(--structure-text-sm);
  margin: 0;
}

/* =========================================================================
   HARVESTED COMPONENT SHAPES — ported from the owner's approved reference
   skeleton (BeltUp Online legacy layout authority, bu-skin-skeleton.css),
   structure only, every class/token renamed to current law on the way in.
   Colors for every class below live exclusively in render-*.css.
   ========================================================================= */

/* --- Muted/small text role (color assigned in render) -------------------- */
.bu-text-muted {
  font-size: 0.85rem;
}

/* --- Section / panel heading shapes -------------------------------------- */
.bu-section-heading {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin-bottom: var(--structure-gap-lg);
}

.bu-panel-title {
  font-size: 0.9rem;
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin-bottom: 1.25rem;
}

.bu-panel-sublabel {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 4px;
  text-transform: uppercase;
  margin-bottom: var(--structure-gap-sm);
}

.bu-panel-headline {
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin-bottom: var(--structure-gap-xl);
}

.bu-panel-footnote {
  margin-top: var(--structure-gap-md);
  font-size: 0.85rem;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.bu-command-header {
  text-align: center;
  margin-bottom: var(--structure-gap-sm);
}

.bu-command-label {
  font-size: 0.8rem;
  font-weight: var(--structure-weight-bold);
  letter-spacing: 8px;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.bu-command-title {
  font-size: clamp(2rem, 5vw, 3.5rem);
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin: 0;
}

/* --- Circular gauge (SVG stroke-dash percentage indicator) ---------------- */
.bu-gauge {
  position: relative;
  width: 100px;
  height: 100px;
}

.bu-gauge svg {
  width: 100%;
  height: 100%;
  display: block;
}

.bu-gauge-value {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--structure-weight-bold);
  font-size: var(--structure-text-base);
}

.bu-gauge-row {
  display: flex;
  gap: var(--structure-gap-lg);
  justify-content: center;
  flex-wrap: wrap;
}

.bu-gauge-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--structure-gap-sm);
}

.bu-gauge-label {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 2px;
  text-transform: uppercase;
}

/* --- 75/25 progression bar (relative track, absolute fill) ---------------- */
.bu-skill-row {
  margin-bottom: var(--structure-gap-md);
}

.bu-skill-row:last-child {
  margin-bottom: 0;
}

.bu-status-labels {
  display: flex;
  justify-content: space-between;
  width: 100%;
  font-size: 0.85rem;
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  margin-bottom: 0.35rem;
}

.bu-progress-track {
  position: relative;
  height: 12px;
  border-radius: 4px;
  width: 100%;
  overflow: hidden;
}

.bu-track-hard {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
}

/* --- Media panel (thumbnail left, content right) --------------------------- */
.bu-media-panel {
  flex-direction: row;
  gap: var(--structure-gap-xl);
  align-items: center;
  flex-wrap: wrap;
}

.bu-media-frame {
  width: 180px;
  height: 110px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.bu-play-circle {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bu-play-icon {
  width: 22px;
  height: 22px;
}

.bu-media-content {
  flex: 1;
  min-width: 240px;
}

.bu-media-label {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 4px;
  text-transform: uppercase;
  margin-bottom: var(--structure-gap-sm);
}

.bu-media-title {
  font-size: 1.25rem;
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: var(--structure-gap-sm);
}

.bu-media-lede {
  margin-bottom: var(--structure-gap-md);
  line-height: 1.5;
}

.bu-badge-tag {
  display: inline-block;
  padding: 0.4rem 0.8rem;
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 1px;
  text-transform: uppercase;
}

/* --- Metric grid (three-up stat cells with center dividers) ---------------- */
.bu-metric-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  align-items: center;
  justify-items: center;
  text-align: center;
}

.bu-metric-cell {
  padding: var(--structure-gap-lg) var(--structure-gap-md);
  text-align: center;
}

.bu-metric-cell .bu-metric-value {
  font-size: 3.5rem;
  line-height: 1;
}

@media (max-width: 720px) {
  /* WT-0915-019 — at 375 the stacked cells sat on three different left edges
     (104 / 105 / 41) and the third ran to x389, past its 293px grid and the panel
     (scrollWidth 372 vs clientWidth 341), so it was clipped. Two causes:
     justify-items:center sized each cell to its content, and a bare 1fr has an
     auto minimum, so the widest word ("TRACKED" at 3.5rem in a display face,
     348px) forced the column wider than the grid. minmax(0, 1fr) + stretch puts
     every cell on the grid's width and one left edge; the value steps down with
     the viewport so the widest word still fits inside it. */
  .bu-metric-grid {
    grid-template-columns: minmax(0, 1fr);
    justify-items: stretch;
  }

  .bu-metric-cell .bu-metric-value {
    font-size: clamp(2rem, 10vw, 3.5rem);
  }
}

/* --- Pillar panels (label / title / body) ---------------------------------- */
.bu-pillar-label {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 4px;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.bu-pillar-title {
  font-size: clamp(1.25rem, 2vw, 1.75rem);
  font-weight: var(--structure-weight-bold);
  line-height: 1.15;
  margin-bottom: var(--structure-gap-md);
}

.bu-pillar-body {
  line-height: 1.6;
}

/* --- Corner panels (label / title / body / bottom-anchored actions) --------- */
.bu-corner-panel {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.bu-corner-label {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 4px;
  text-transform: uppercase;
}

.bu-corner-title {
  font-size: 1.75rem;
  font-weight: var(--structure-weight-bold);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin: 0;
}

.bu-corner-body {
  line-height: 1.6;
  margin: 0;
}

.bu-corner-actions {
  margin-top: auto;
  padding-top: var(--structure-gap-md);
}

/* --- Slat (thin horizontal work-item strip: level | info | action) --------- */
.bu-slat {
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--structure-gap-md);
  padding: 0.75rem var(--structure-gap-md);
}

.bu-slat-level {
  font-weight: var(--structure-weight-bold);
  font-size: 0.95rem;
  letter-spacing: 1px;
  text-align: center;
}

.bu-slat-info h4 {
  text-transform: uppercase;
  font-size: 0.9rem;
  letter-spacing: 1px;
  margin: 0 0 0.35rem 0;
}

.bu-slat-info p {
  margin: 0 0 0.4rem 0;
  font-size: var(--structure-text-xs);
  letter-spacing: 0.5px;
}

.bu-slat .bu-progress-track {
  height: 4px;
}

.bu-slat-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

/* WT-0915-018 — on a phone the auto-width action column (SCAN IN measured 149px)
   squeezed the info column to 9px, 0px and 36px, so each DAILY QUESTS tile grew to
   298 / 316 / 225px tall with its title broken a letter at a time. Below the
   narrow breakpoint the action drops onto its own row under level + info. */
@media (max-width: 600px) {
  .bu-slat {
    grid-template-columns: 80px minmax(0, 1fr);
  }

  .bu-slat-actions {
    grid-column: 1 / -1;
  }
}

/* --- Status dot (pulse indicator) ------------------------------------------- */
.bu-status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}

@keyframes bu-alert-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.35); opacity: 0.6; }
}

.bu-status-dot.is-alert {
  animation: bu-alert-pulse 1.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .bu-status-dot.is-alert {
    animation: none;
  }
}

/* --- Stealth link (uppercase, quiet) ----------------------------------------- */
.bu-link-stealth {
  text-decoration: none;
  font-weight: var(--structure-weight-bold);
  font-size: 0.8rem;
  text-transform: uppercase;
}

/* --- Global footer (brand column + link columns + copyright bar) ------------- */
.bu-footer {
  margin-top: var(--structure-gap-2xl);
  /* WT-0915-053 / WT-0915-049 — bottom padding was 0, so the last footer link sat
     flush on the page's last pixel (bottom y3818 on a 3822px page), and on a phone
     the fixed '?' report trigger (44px tall, 12px off the bottom) sat on top of it
     with no way to scroll it clear. The reserve is the trigger's height plus a gap,
     so the last row always clears it. */
  padding: var(--structure-gap-2xl) var(--structure-gap-xl) calc(var(--structure-touch-min) + var(--structure-gap-xl));
  position: relative;
  z-index: var(--structure-z-rail);
}

.bu-footer-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--structure-gap-lg);
  max-width: var(--structure-container-max);
  margin: 0 auto;
}

.bu-footer-brand {
  grid-column: span 6;
}

.bu-footer-links {
  grid-column: span 2;
}

.bu-footer-tagline {
  margin-top: 0.75rem;
  max-width: 32ch;
  line-height: 1.5;
}

.bu-footer-heading {
  font-size: var(--structure-text-xs);
  font-weight: var(--structure-weight-bold);
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.bu-footer-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  /* WT-0915-053 — 0, not gap-sm: each link below is now a 44px row, so the target
     itself carries the rhythm (44px pitch, was 18px links on a 33px pitch). */
  gap: 0;
}

/* WT-0915-053 (desktop leg) — at 1440 and 1024 every footer link was an 18px-tall
   target (Terms 37x18), under the Primer's 44px law in both dimensions; only the
   phone block below lifted the height. Every width now gets the full target. */
.bu-footer-list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--structure-touch-min);
  min-width: var(--structure-touch-min);
  font-size: 0.85rem;
}

.bu-footer-copyright {
  max-width: var(--structure-container-max);
  margin: var(--structure-gap-xl) auto 0;
  padding: 1.25rem 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--structure-text-xs);
}

.bu-footer-lab-link {
  opacity: 0.5;
  text-decoration: none;
  font-size: var(--structure-text-xs);
}

@media (max-width: 900px) {
  .bu-footer-brand {
    grid-column: span 12;
  }

  .bu-footer-links {
    grid-column: span 4;
  }
}

@media (max-width: 600px) {
  .bu-footer-links {
    grid-column: span 12;
  }
}

/* -----------------------------------------------------------------------
   Greyscale fallback canvas — structural surface reference only. These
   two values referenced here by name only (canvas, surface) are the grounded baseline
   documented for the greyscale-skeleton skin. They are declared as tokens
   in render-greyscale-skeleton.css, NOT as literals here — this comment
   exists only to document intent; this file contains zero color literals.
   ----------------------------------------------------------------------- */

/* -----------------------------------------------------------------------
   .bu-table-wrapper — horizontal scroll container for a wide table, so a
   table that cannot fit the viewport scrolls itself instead of forcing the
   whole page to scroll sideways.
   ----------------------------------------------------------------------- */
.bu-table-wrapper {
  overflow-x: auto;
}

/* -----------------------------------------------------------------------
   Phone ergonomics (2026-08-22, from the layout walkthrough).

   A page may be DESIGNED for desktop, but it must be USABLE on a phone —
   these rules only fix reachability and fit, never appearance, so they are
   structure and belong in the Primer.
   ----------------------------------------------------------------------- */
@media (max-width: 768px) {
  /* .bu-link-stealth is a deliberately quiet 0.8rem footer link. Quiet is fine;
     un-tappable is not — it accounted for 107 of the 120 undersized touch
     targets found across the site, because it appears in the footer of every
     page. Given a real target height it stays visually identical and becomes
     hittable. */
  .bu-link-stealth {
    display: inline-flex;
    align-items: center;
    min-height: var(--structure-touch-min);
  }

  /* Tables cannot be made to fit a 390px screen without lying about the data,
     so let them scroll horizontally INSIDE their own box rather than pushing
     the whole page sideways. Applied to the element itself because most tables
     in this codebase are not wrapped in .bu-table-wrapper; `max-width: 100%`
     keeps the scroll contained to the table. */
  .bu-table-wrapper,
  table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Tighter cell padding so fewer columns need scrolling in the first place. */
  table th,
  table td {
    padding: 0.5rem;
    white-space: nowrap;
  }

  /* Native checkboxes and radios render ~13px, well under any reachable target.
     Enlarging the control itself keeps the hit area on the control (not just its
     label), which is what a thumb actually aims at. */
  input[type="checkbox"],
  input[type="radio"] {
    min-width: 24px;
    min-height: 24px;
  }

  /* A label wrapping a control is the real target — give it the full height so
     tapping the words works, not just the 24px box. */
  .bu-check-label,
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) {
    display: inline-flex;
    align-items: center;
    gap: var(--structure-gap-sm);
    min-height: var(--structure-touch-min);
  }

  /* Text inputs, selects and file pickers: the Primer's 44px law applies on a
     phone above all, where these were rendering short. */
  .bu-input,
  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="number"],
  input[type="date"],
  input[type="password"],
  input[type="url"],
  input[type="file"],
  select,
  textarea {
    min-height: var(--structure-touch-min);
  }

  /* A <summary> styled as a control is a control. */
  summary {
    min-height: var(--structure-touch-min);
    display: flex;
    align-items: center;
  }

  /* WT-0915-038 — a bare h1 kept the desktop 3rem (48px) on a phone: the /pricing
     title broke over four lines (293x221 at 375) and pushed the first /inquire
     field down to y575. One step down the structural scale (28px), next to the
     32px Home's hero already lands on. A class or skin heading rule still wins
     (specificity 0,0,1). */
  h1 {
    font-size: var(--structure-text-xl);
  }
}

/* -----------------------------------------------------------------------
   .bu-panel.bu-brick — padding collision repair (2026-08-23).
   Markup legitimately combines the two (`class="bu-panel bu-brick"`), but
   .bu-panel sets padding: var(--structure-gap-lg) and .bu-brick sets
   `var(--structure-gap-sm) 0`. Same specificity, .bu-brick declared later, so
   it won and zeroed the HORIZONTAL padding — content then sat flush against
   the panel edge. Under skins that draw a corner ornament (Fight Night's 35px
   cobalt wedge on .bu-panel::before) that clipped the first letter of every
   panel heading. A panel is a padded surface first; being a brick as well must
   not remove that.
   ----------------------------------------------------------------------- */
.bu-panel.bu-brick {
  padding: var(--structure-gap-lg);
}

/* -----------------------------------------------------------------------
   US-182 (#227) / R-1016-02: preproduction dev/test overlay + banner.
   Rendered only when Environment:Preproduction is true. Uses a DEDICATED high-contrast
   pair (not skin tokens) so text is >= 4.5:1 in every skin (greyscale, executive-blue,
   fight-night): body #f5f7fa on #0b0e13 (~17:1), heading/banner/button amber #fbbf24
   against #0b0e13 (~11:1) and #1a1300 on #fbbf24 (~11:1).
   No-JS: the overlay blocks via CSS; the "I understand" anchor targets #bu-preprod-ack,
   which hides it (:target). With JS the script handles sessionStorage + focus trap.
   ----------------------------------------------------------------------- */
.bu-preprod-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: flex-start; /* top-aligned + scrollable: the top is never clipped on short viewports */
  justify-content: center;
  padding: var(--structure-gap-lg);
  overflow-y: auto;
  background-color: #05070a;
  color: #f5f7fa;
}
.bu-preprod-overlay[hidden],
#bu-preprod-ack:target + .bu-preprod-overlay { display: none; }
html.bu-preprod-acked .bu-preprod-overlay { display: none; }
.bu-preprod-dialog {
  max-width: 40rem;
  width: 100%;
  margin: auto; /* centres vertically when it fits, scrolls from the top when it does not */
  padding: var(--structure-gap-xl, var(--structure-gap-lg));
  border: 3px solid #fbbf24;
  background-color: #0b0e13;
  color: #f5f7fa;
}
.bu-preprod-dialog h1 { color: #fbbf24; margin-top: 0; }
.bu-preprod-dialog .bu-btn {
  display: inline-block;
  text-decoration: none;
  margin-top: var(--structure-gap-md);
  background-color: #fbbf24;
  color: #1a1300;
  border: 2px solid #fbbf24;
  font-weight: 700;
}
.bu-preprod-dialog .bu-btn:hover { background-color: #fcd34d; color: #1a1300; }
.bu-preprod-dialog .bu-btn:focus-visible { outline: 3px solid #ffffff; outline-offset: 2px; }
.bu-preprod-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 9000;
  padding: 2px var(--structure-gap-md);
  text-align: center;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  background-color: #fbbf24;
  color: #1a1300;
}
.bu-preprod-checkout-notice {
  border-left: 4px solid #fbbf24;
  padding-left: var(--structure-gap-sm);
}
