/* =========================================================
   ControlIO — Layout Primitives
   Handle: wb-layout · depends on wb-tokens · Step 3 Pass E

   Containers, page shell, breadcrumb, page header, footer
   structure, section rhythm.

   The measured problem this solves: at 3440px the footer's
   content column rendered 323px wide, marooned in the middle
   of the viewport, while the catalogue filter input stretched
   to 1345px. Neither was constrained by a container — one had
   nothing to fill, the other had nothing to stop it.
   ========================================================= */

/* ---------------------------------------------------------
   CONTAINERS

   Four widths, chosen by what the content is, not by page.
   Checkout does not want the same measure as a product grid.
   --------------------------------------------------------- */

.wbc-container,
.wbc-container--content{
  width: 100%;
  max-width: var(--container-content);
  margin-inline: auto;
  padding-inline: var(--content-gutter);
  box-sizing: border-box;
}
.wbc-container--narrow{ max-width: var(--container-narrow); }   /* forms, checkout */
.wbc-container--reading{ max-width: var(--container-reading); } /* prose */
.wbc-container--wide{ max-width: var(--container-wide); }       /* grids, galleries */
.wbc-container--full{ max-width: none; padding-inline: 0; }     /* edge-to-edge media */

.wbc-container--narrow,
.wbc-container--reading,
.wbc-container--wide,
.wbc-container--full{
  width: 100%;
  margin-inline: auto;
  box-sizing: border-box;
}
.wbc-container--narrow,
.wbc-container--reading,
.wbc-container--wide{ padding-inline: var(--content-gutter); }

/* .wbc-prose and the reading measures live in typography.css, which owns text
   rhythm. They were briefly defined in both files — the exact duplication this
   system exists to prevent. */

/* ---------------------------------------------------------
   PAGE SHELL
   header · breadcrumb · page header · main · footer
   --------------------------------------------------------- */

.wbc-page{
  display: flex;
  flex-direction: column;
  min-height: 100dvh;   /* dvh, not vh: mobile browser chrome changes vh */
}
.wbc-page__main{ flex: 1 0 auto; }

/* .wbc-section is NOT defined here. The theme already owns that class as a
   page-composition container with five template usages, and its shorthand
   `padding: 0 24px` silently reset any padding-block a primitive set — a
   collision that would have looked like the rhythm simply not working.
   Vertical rhythm is available as .wbc-stack instead, and the theme's section
   container is unified in layout/base.css. */
.wbc-stack{ padding-block: var(--section-gap); }
.wbc-stack + .wbc-stack{ padding-block-start: 0; }

/* ---------------------------------------------------------
   BREADCRUMB
   --------------------------------------------------------- */

.wbc-breadcrumb{ padding-block: var(--space-3); font-size: var(--text-sm); }
.wbc-breadcrumb__list{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
}
.wbc-breadcrumb__item{ display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; }
.wbc-breadcrumb__item + .wbc-breadcrumb__item::before{
  content: "/";
  color: var(--border-strong);
  flex: none;
}
.wbc-breadcrumb__link{ color: var(--muted); text-decoration: none; }
.wbc-breadcrumb__link:hover{ color: var(--text); text-decoration: underline; }
.wbc-breadcrumb__link:focus-visible{
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}
.wbc-breadcrumb__current{
  color: var(--text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* On a phone a deep taxonomy trail wraps to three lines and pushes the page
   title below the fold. Collapse to the parent plus the current page, which is
   the part that carries orientation. */
@media (max-width: 767px){
  .wbc-breadcrumb__item{ display: none; }
  .wbc-breadcrumb__item:nth-last-child(-n+2){ display: inline-flex; }
  .wbc-breadcrumb__item:nth-last-child(2)::before{ content: ""; }
  .wbc-breadcrumb__current{ max-width: 60vw; }
}

/* ---------------------------------------------------------
   PAGE HEADER
   eyebrow · title · description · actions
   --------------------------------------------------------- */

.wbc-pagehead{
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-4);
  padding-block: var(--space-4) var(--space-5);
}
.wbc-pagehead__text{ flex: 1 1 22rem; min-width: 0; }
.wbc-pagehead__eyebrow{
  margin: 0 0 var(--space-1);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--accent-strong);
}
.wbc-pagehead__title{
  margin: 0;
  /* Scales with the viewport but is clamped at both ends: a heading must not
     dominate a phone, nor keep growing on an ultrawide monitor. */
  font-size: clamp(var(--text-xl), 1.25rem + 1.6vw, var(--text-3xl));
  line-height: var(--leading-tight);
  font-weight: 800;
  letter-spacing: -.01em;
}
.wbc-pagehead__desc{
  margin: var(--space-2) 0 0;
  max-width: 60ch;
  color: var(--muted);
  line-height: var(--leading-base);
}
.wbc-pagehead__actions{
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-inline-start: auto;
}
@media (max-width: 767px){
  .wbc-pagehead__actions{ margin-inline-start: 0; width: 100%; }
  .wbc-pagehead__actions > .wbc-btn{ flex: 1 1 auto; }
}

/* ---------------------------------------------------------
   FOOTER

   Grouped navigation and factual trust information.
   --------------------------------------------------------- */

.wbc-footer{
  margin-block-start: var(--space-8);
  background: var(--surface-muted);
  border-block-start: 1px solid var(--border);
  color: var(--text);
}
.wbc-footer__inner{ padding-block: var(--space-7); }

.wbc-footer__groups{
  display: grid;
  gap: var(--space-6) var(--space-5);
  /* One column on a phone, filling out as space allows. auto-fit rather than a
     fixed count so the tablet case is not a squeezed desktop. */
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
/* Cap the column count so groups do not spread across an ultrawide monitor with
   metres of space between them. */
@media (min-width: 1512px){
  .wbc-footer__groups{ grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.wbc-footer__group{ min-width: 0; }
.wbc-footer__heading{
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text);
}
.wbc-footer__list{ margin: 0; padding: 0; list-style: none; }
.wbc-footer__list li + li{ margin-block-start: var(--space-1); }
.wbc-footer__link{
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);   /* footer links are tapped, not read */
  color: var(--muted);
  text-decoration: none;
  font-size: var(--text-sm);
}
.wbc-footer__link:hover{ color: var(--text); text-decoration: underline; }
.wbc-footer__link:focus-visible{
  outline: var(--focus-width) solid var(--focus-color);
  outline-offset: var(--focus-offset);
}

/* Factual reassurance only — no fabricated urgency, no invented badges. */
.wbc-footer__trust{
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-start: var(--space-6);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--border);
}
.wbc-trust{
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  flex: 1 1 14rem;
  min-width: 0;
}
.wbc-trust__icon{
  flex: none;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--surface);
  color: var(--accent-strong);
}
.wbc-trust__title{ margin: 0; font-size: var(--text-sm); font-weight: 700; }
.wbc-trust__body{ margin: 0; font-size: var(--text-sm); color: var(--muted); }

.wbc-footer__base{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border);
  font-size: var(--text-sm);
  color: var(--muted);
}
.wbc-footer__base p{ margin: 0; }
.wbc-footer__legal{
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-inline-start: auto;
}

/* Clear the fixed bottom tab bar so the last footer row is reachable. */
@media (max-width: 1199px){
  .wbc-footer__inner{
    padding-block-end: calc(var(--space-7) + var(--wbc-tabbar-height, 0px));
  }
}

/* ---------------------------------------------------------
   ANNOUNCEMENT / UTILITY BAR (brief 3.54)

   ONE bar, above the header. Deliberately singular: the rule
   this encodes is that promotional banners do not stack. If a
   second message matters, it replaces the first or it belongs
   somewhere the customer actually chose to look.

   Not for errors — those are notices, which sit in the page
   next to whatever they concern.
   --------------------------------------------------------- */

.wbc-utilitybar{
  background: var(--surface-muted);
  border-block-end: 1px solid var(--border);
  color: var(--text);
  font-size: var(--text-sm);
}

.wbc-utilitybar--accent{
  background: var(--accent-strong);
  border-block-end-color: transparent;
  color: var(--on-accent);
}

.wbc-utilitybar__inner{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--control-height-sm);
  padding-block: var(--space-2);
}

.wbc-utilitybar__message{
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}

.wbc-utilitybar__actions{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-inline-start: auto;
}

.wbc-utilitybar__link{
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-target-min);
  color: inherit;
  text-decoration: underline;
  text-underline-offset: .15em;
  font-weight: 600;
}
.wbc-utilitybar__link:focus-visible{
  outline: var(--focus-width) solid currentColor;
  outline-offset: var(--focus-offset);
}

.wbc-utilitybar__dismiss{
  flex: none;
  color: inherit;
}

/* On a phone the bar competes directly with the header for the most valuable
   space on the screen, so contact actions drop away and only the message
   survives. Anything essential belongs in the page, not in a bar. */
@media (max-width: 767px){
  .wbc-utilitybar__actions{ display: none; }
  .wbc-utilitybar__inner{ padding-block: var(--space-1); }
  .wbc-utilitybar__message{ font-size: var(--text-xs); }
}

/* ---------------------------------------------------------
   STICKY CONTRACT (brief 3.61)

   Sticky is a budget, not a default. Each region below opts in
   explicitly, and every one of them reserves space via a
   custom property so the next one down knows where it can sit.
   Nothing else in the system may use position: sticky.
   --------------------------------------------------------- */

.wbc-sticky-top{
  position: sticky;
  inset-block-start: var(--wbc-sticky-offset, 0px);
  z-index: var(--z-sticky);
}

/* A sticky panel must never be taller than the viewport it sticks inside, or
   its lower half becomes permanently unreachable. This matters most at
   1366x768 and in mobile landscape. */
.wbc-sticky-panel{
  position: sticky;
  inset-block-start: calc(var(--wbc-sticky-offset, 0px) + var(--space-4));
  max-height: calc(100dvh - var(--wbc-sticky-offset, 0px) - var(--space-8));
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Below the laptop breakpoint a sticky side panel would consume the whole
   screen, so it reverts to normal flow. */
@media (max-width: 1199px){
  .wbc-sticky-panel{
    position: static;
    max-height: none;
    overflow: visible;
  }
}

@media (max-height: 560px){
  /* Landscape phones: nothing sticks. There is not enough height to give any
     of it away permanently. */
  .wbc-sticky-top,
  .wbc-sticky-panel{ position: static; }
}

/* ---------------------------------------------------------
   SIDEBAR / FILTER LAYOUT (brief 3.60)

   The architecture only. Filter behaviour is Step 7; this is
   the shell it will drop into.
   --------------------------------------------------------- */

.wbc-withsidebar{
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
}

/* Sidebar appears only where there is genuinely room for it. Below this the
   filter trigger opens the shared drawer instead — one implementation, two
   presentations. */
@media (min-width: 1200px){
  .wbc-withsidebar{
    grid-template-columns: minmax(14rem, 17rem) minmax(0, 1fr);
    align-items: start;
  }
  .wbc-withsidebar--end{
    grid-template-columns: minmax(0, 1fr) minmax(14rem, 17rem);
  }
  .wbc-withsidebar__aside{ position: relative; }
}

.wbc-withsidebar__main{ min-width: 0; }

/* The mobile filter trigger. Hidden once the sidebar exists. */
.wbc-filtertrigger{ display: inline-flex; }
@media (min-width: 1200px){
  .wbc-filtertrigger{ display: none; }
}

/* Toolbar above a results grid: count on the left, controls on the right. */
.wbc-resultsbar{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding-block: var(--space-3);
}
.wbc-resultsbar__count{
  color: var(--muted);
  font-size: var(--text-sm);
}
.wbc-resultsbar__controls{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: auto;
}
