/* ============================================
   Layout

   Page structure: body, main wrapper, aurora
   background, content well, site header,
   step page containers, composite steps.
   ============================================ */

/* ============================================
   STANDARD BREAKPOINTS
   
   Mobile:  0px - 767px (default styles, mobile-first)
   Tablet:  768px - 1023px (min-width: 768px)
   Desktop: 1024px+ (min-width: 1024px)
   
   Pixel widths:
   - sm:  640px  (small mobile landscape)
   - md:  768px  (tablet portrait)
   - lg:  1024px (desktop / tablet landscape)
   - xl:  1280px (large desktop)
   - 2xl: 1536px (extra large desktop)
   
   Current usage: md (768px) and lg (1024px)
   
   TODO: Designer review - are these breakpoints optimal
         for our user demographics and design requirements?
   ============================================ */

:root {
  /* Pre-hydration FALLBACK ONLY for the visual height of .site-header (including its progress
     bar). Used by mobile-only overlays (e.g. quote details / agent contact takeovers) and by the
     sticky quotes-edit banner to anchor below the header so nothing gets covered.

     This calc() assumes the header's grid-template-columns: 1fr auto 1fr row never wraps or
     overflows at any width within a breakpoint bucket — true often enough to be a safe first
     paint, but not guaranteed on every real device (a 320px-wide phone doesn't fit the same as a
     767px one, and both are "mobile" here), which previously caused the quotes-edit banner's
     `top` offset to come up short and render behind the header on some phones.

     NavBar.razor.js measures .site-header's REAL rendered height via ResizeObserver (plus a
     one-shot re-check once web fonts finish loading, since a font swap can change the logo/text
     metrics after this first paint) and overwrites this custom property on <html> once mounted —
     see observeHeaderHeight() there. That JS-authored value always wins once it exists (an
     element's own inline style beats any stylesheet rule, media query or not), so this block only
     matters for the brief window before NavBar's first render. Kept close to correct anyway
     (vertical padding + tallest header-row child) so that window never visibly flashes. */
  --site-header-height: calc(1rem + 1rem + max(40px, 36px));

  /* Shared by .step-page's own padding-top (below) and anything outside .step-page that needs to
     cancel that same padding via a negative margin (the mobile quotes-edit banner, see
     QuotesPresentationComponent.razor.css) — defined once here so the two can't hand-drift apart
     from each other, which is exactly the kind of mismatch that caused the banner-behind-header
     bug this comment block is explaining. */
  --step-page-top-padding: clamp(12px, 5dvh - var(--spacing-lg), var(--spacing-4xl));

  /* Shared by .site-header-back's own width/height and the mobile scroll-collapsed grid-column
     width below, so the back button's column can shrink to exactly its size without hand-copying
     the same "40px" in two places. */
  --site-header-back-size: 40px;
}

@media (min-width: 768px) {
  :root {
    --site-header-height: calc(1.25rem + 1.25rem + max(40px, 40px));
  }
}

@media (min-width: 1024px) {
  :root {
    --site-header-height: calc(2rem + 2rem + max(40px, var(--spacing-3xl)));
  }
}

body {
  height: 100%;
  width: 100%;
  font-family: var(--font-family);
  background-color: var(--theme-bg, var(--color-background));
  color: var(--color-text);
}

.main-content-wrapper {
  height: 100%;
  width: 100%;
  display: flex;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  position: relative;
}

/* Aurora background — frosted glass effect behind content */
.main-content-wrapper::before {
  content: '';
  position: fixed;
  inset: -100px;
  z-index: -1;
  background:
    radial-gradient(circle 450px at 5% 30%, var(--theme-aurora-1, rgba(87, 71, 248, 0.08)), transparent 70%),
    radial-gradient(circle 400px at 90% 10%, var(--theme-aurora-2, rgba(0, 186, 241, 0.07)), transparent 70%),
    radial-gradient(circle 500px at 50% 85%, var(--theme-aurora-3, rgba(58, 110, 245, 0.06)), transparent 70%),
    radial-gradient(circle 350px at 75% 60%, var(--theme-aurora-4, rgba(0, 186, 241, 0.05)), transparent 70%),
    radial-gradient(circle 300px at 20% 75%, var(--theme-aurora-5, rgba(87, 71, 248, 0.05)), transparent 70%);
  filter: blur(80px);
  pointer-events: none;
}

.content-container {
  display: flex;
  flex: 1 1 100%;
  flex-direction: column;
  padding: var(--spacing-xl) var(--spacing-lg);
  width: 100%;
  max-width: var(--max-content-width);
  margin: 0 auto;
}

/* ============================================
   Site Header — White bar with centered logo + back button
   3-column grid keeps logo centered regardless of back button width. On mobile, once the
   quotes-edit banner collapses into the header (see below), the back-slot column shrinks and
   the logo shifts left with it instead of staying centered — real grid layout, not a transform.
   z-index: 10 (content=1, aurora=-1)
   ============================================ */

.site-header {
  width: 100%;
  padding: 1rem 1.5rem;
  background: var(--color-surface, #FFFFFF);
  display: grid;
  /* The last column uses minmax(max-content, 1fr) rather than a plain 1fr — a plain 1fr can
     shrink below its content's natural width, which would wrap or clip .site-header-edit-btn's
     icon + "Edit info" text on narrow phones. max-content as the floor guarantees that column is
     always at least wide enough for its content unwrapped, while still behaving exactly like 1fr
     (sharing space evenly with the back-button column) whenever the content is small/empty, so
     desktop and the empty-spacer case look unchanged. */
  grid-template-columns: 1fr auto minmax(max-content, 1fr);
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-header-back-slot {
  justify-self: start;
}

.site-header-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--site-header-back-size);
  height: var(--site-header-back-size);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: var(--theme-primary, var(--color-primary));
  border-radius: 50%;
  transition: background-color var(--transition-fast, 0.15s ease);
}

@media (hover: hover) and (pointer: fine) {
  .site-header-back:hover {
    background-color: var(--theme-primary-focus, var(--color-focus));
  }
}

.site-header-logo {
  justify-self: center;
  height: 36px;
  width: 180px;
  background: var(--theme-logo-url) no-repeat center / contain;
}

.site-header-spacer {
  /* empty right column to balance the grid, except on mobile Quotes screens once scrolled past
     the results heading — see .site-header-edit-btn below */
  justify-self: end;
}

/* ============================================
   Mobile scroll-linked header transition (Quotes screen only, <=768px)
   QuotesPresentationComponent.razor.js toggles `quotes-banner-collapsed` on <body> once
   `.quotes-results-header` scrolls behind the sticky header + edit banner. NavBar only mounts
   this button while on the Quotes step (see NavBar.razor.cs ShowEditButton) — it is hidden here
   via opacity/visibility (not display) purely so the fade can be animated; on every other
   breakpoint it's simply `display: none` below and never enters the layout at all.
   ============================================ */
.site-header-edit-btn {
  display: none;
}

@media (max-width: 768px) {
  /* Deliberately NOT animated (no `transition: grid-template-columns`). Animating a grid track's
     size is layout-triggering — the browser must reflow the header on every frame of the
     transition — which is fine at rest but visibly janky while the page is simultaneously
     scrolling (exactly what's happening here, since this only ever toggles mid-scroll). The
     column change below is real, correct layout math (the back-slot column genuinely shrinks to
     var(--site-header-back-size), it isn't guessed), it just now happens in a single instant
     reflow instead of an animated one. NavBar.razor.js supplies the smoothness instead, via a
     FLIP-style `transform: translateX()` on .site-header-logo computed from the logo's real
     before/after position — compositor-only, so it stays smooth regardless of the reflow above
     or of concurrent scrolling. See setQuotesBannerCollapsed() there. */
  .site-header-logo {
    /* The logo's own column is always auto-sized to exactly the logo's width, so start vs.
       center make no visual difference on their own — this is here so the logo unambiguously
       hugs the back-slot column rather than floating in the middle of it once that column
       shrinks (below), which is what actually reads as "the logo slides left." The FLIP
       transform above is what makes that instant shift read as a slide. */
    justify-self: start;
    transition: transform var(--transition-base);
  }

  .site-header-edit-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-sm);
    background-color: var(--color-surface);
    color: var(--color-primary-text);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    padding: var(--spacing-sm) var(--spacing-md);
    font-size: var(--font-size-xs);
    font-weight: 500;
    font-family: var(--theme-font-ui, var(--font-family));
    /* Belt-and-suspenders alongside .site-header's minmax(max-content, 1fr) column: guarantees
       the label never wraps even if something else ever constrains this column's width. */
    white-space: nowrap;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    /* Same duration as the rest of this transition (banner opacity/height, logo transform above)
       so the whole collapse/expand reads as one coordinated motion rather than mismatched
       timings — this previously used --transition-slow on its own. */
    transition: opacity var(--transition-base), visibility var(--transition-base);
  }

  body.quotes-banner-collapsed .site-header {
    /* Shrinks the back-slot column to exactly the back button's own size (rather than sharing
       1fr with the edit-button column), pushing the logo as far left as the grid allows — real
       layout, not a guessed transform distance, and it stays correct regardless of whether the
       back button happens to be showing on this particular step. */
    grid-template-columns: var(--site-header-back-size) auto minmax(max-content, 1fr);
  }

  body.quotes-banner-collapsed .site-header-edit-btn {
    opacity: 1;
    visibility: visible;
  }
}

/* Progress bar — bottom border of header */
.site-header-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: fit-content;
  background-color: var(--color-border-light, #EDF2F7);
}

/* Tablet+ */
@media (min-width: 768px) {
  .site-header {
    padding: 1.25rem 2rem;
  }

  .site-header-logo {
    height: 40px;
    width: 220px;
  }
}

/* Desktop landscape */
@media (min-width: 1024px) {
  .site-header {
    padding: 2rem 3rem;
  }

  .site-header-logo {
    height: var(--spacing-3xl);
    width: 280px;
  }
}

/* ============================================
   Step Page Containers — Top-aligned, fluid spacing
   ============================================
   Flex chain: .main-content-wrapper → .content-container → .step-page → .input-container
   Each level uses flex:1 to fill available height.

   Content starts from the top with viewport-relative spacing via clamp().
   This compresses on short viewports (iPad landscape) and breathes on tall ones.
   ============================================ */

/* Groups step counter + step component — tight internal spacing */
.step-content {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.step-page {
  /* animation: fadeInSlideUp — defined in animations.css */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  flex: 1;
  justify-content: flex-start;
  padding-top: var(--step-page-top-padding);
  gap: clamp(var(--spacing-lg), 4dvh, var(--spacing-3xl));
}

.input-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
}

/* Wrapper for all interactive content inside .input-container.
   Provides consistent spacing below prompt/subtext regardless
   of whether subtext is present. */
.input-form-body {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: clamp(var(--spacing-lg), 3dvh, var(--spacing-2xl));
}

.input-form-column {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  gap: var(--spacing-md);
}

/* Container for grouping an input field with its error message */
.input-field-container {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  width: 100%;
}

/* Side-by-side fields at wider viewports (name, DOB, contact info) */
.input-form-column.inline-fields .input-field {
  max-width: none;
}

@media (min-width: 768px) {
  .input-form-column.inline-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0px, 1fr));
  }
}

/* ============================================
   Composite Step Container
   When multiple questions are rendered on one page (CompositeInputComponent),
   each inner .input-container shrinks to fit its content so the group
   centers naturally. The page scrolls if content exceeds viewport.
   ============================================ */
.composite-step-container {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  flex: 1;
  gap: var(--spacing-md);
  width: 100%;
}

.composite-step-container .input-container {
  flex: 0 1 auto;
}

.composite-step-container .input-subtext:empty {
  display: none;
}

.composite-step-container .input-prompt:empty {
  display: none;
}