/* ==========================================================================
   THE DESIGNERS HUB — base layer
   Reset, typography and shared components. All values resolve to tokens.css,
   which is read from the Figma file. No literal values are invented here.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overflow-x: clip; /* safety net: no section may widen the document */
}

body {
  margin: 0;
  background: var(--color-page-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
svg { display: block; max-width: 100%; }

/* --- Fetched-partial height reservation -------------------------------------
   The header and footer are fetched by include.js, which REPLACES the
   placeholder <div> outright. An empty div is 0 tall, so until the fetch
   resolved every page rendered with `main` at y:0 and then jumped down by the
   header's full height about 150ms in. Reproduced identically on index,
   consultations and membership, and it has been a known site-wide defect for
   a while.

   Reserving the height the partial is about to occupy removes the shift. The
   values are the chrome's own pinned heights, measured rather than assumed:

     header  76 at >=1200, 81 below   (both variants — the standard header and
                                       the minimal checkout one are the same
                                       height at each breakpoint)
     footer  220 at >=768, 388 below  (both variants — standard and slim)

   This cannot double-count once the partial lands: the placeholder is removed
   from the DOM by the replace, so the reservation only ever applies while the
   real chrome is absent.
--------------------------------------------------------------------------- */
[data-include*="header"] { min-height: 81px; }
[data-include*="footer"] { min-height: 388px; }

@media (min-width: 768px) {
  [data-include*="footer"] { min-height: 220px; }
}

@media (min-width: 1200px) {
  [data-include*="header"] { min-height: 76px; }
}

/* --- Canvas scale -----------------------------------------------------------
   The design is a fixed 1440 frame. Zooming the document by
   (window width / 1440) makes the effective viewport exactly 1440, so every
   Figma coordinate lands unchanged while the page fills the screen.
   --canvas-scale is set by the inline script in the document head; it stays 1
   below the desktop breakpoint, where the reflowed layout applies instead.
--------------------------------------------------------------------------- */
@media (min-width: 1200px) {
  body { zoom: var(--canvas-scale, 1); }
}

a { color: inherit; text-decoration: none; }

/* --- Breakpoint-swapped copy -------------------------------------------------
   Several strings differ between the 1440 and 390 frames (CTA labels on home,
   the case-study "What we discovered:" / "Before:" label on the stage pages).
   Both ship and the breakpoint picks one. These are content differences
   between the two Figma frames, not build decisions — all are flagged.
--------------------------------------------------------------------------- */
.lbl-narrow { display: none; }

@media (max-width: 767px) {
  .lbl-wide   { display: none; }
  .lbl-narrow { display: inline; }
}

h1, h2, h3, h4, p, figure { margin: 0; }

ul { margin: 0; padding: 0; list-style: none; }

/* --- Layout container -------------------------------------------------------
   Desktop content column is 1280 inside the 1440 frame. */
.container {
  width: 100%;
  max-width: calc(var(--container-max) + (var(--page-pad-desk) * 2));
  margin-inline: auto;
  padding-inline: var(--page-pad-mob);
}

@media (min-width: 768px) {
  .container { padding-inline: var(--page-pad-tab); }
}

@media (min-width: 1200px) {
  .container { padding-inline: var(--page-pad-desk); }
}

/* --- Typography -------------------------------------------------------------
   Sizes scale down at tablet/mobile. Desktop values are verified against the
   Figma desktop frame; the smaller steps are a proportional reduction and are
   pending verification against the 768 / 390 frames. */
.h1 {
  font-family: var(--font-heading);
  font-weight: var(--fw-bold);
  font-size: 26px;
  line-height: var(--lh-h1);
  text-transform: uppercase;
}

.h2 {
  font-family: var(--font-heading);
  font-weight: var(--fw-semi);
  font-size: 22px;
  line-height: 1.2;
  text-transform: uppercase;
}

.h2--medium { font-weight: var(--fw-med); }

.lead {
  font-size: 15px;
  font-weight: var(--fw-reg);
  line-height: 1.5;
}

.lead--light { font-weight: var(--fw-light); }

.eyebrow {
  font-weight: var(--fw-semi);
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
}

.meta {
  font-size: var(--fs-meta);
  font-weight: var(--fw-reg);
  line-height: 1.4;
}

@media (min-width: 768px) {
  .h1   { font-size: 32px; }
  .h2   { font-size: 28px; }
  .lead { font-size: 17px; }
}

@media (min-width: 1200px) {
  .h1   { font-size: var(--fs-h1); }
  .h2   { font-size: var(--fs-h2); }
  .lead { font-size: var(--fs-lead); line-height: 1.35; }
}

/* --- Buttons (Figma component 1262:297 / 2129:1375) -------------------------
   gold fill #D8A025, padding 17/55, height 52, label Open Sans 700 14 UPPER */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--btn-gap);
  min-height: var(--btn-h);
  padding: var(--btn-pad-y) var(--btn-pad-x);
  font-family: var(--font-button);
  font-weight: var(--fw-bold);
  font-size: var(--fs-button);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  border: 0;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}

.btn--gold {
  background: var(--gold);
  color: var(--white);
}

.btn--gold:hover,
.btn--gold:focus-visible { background: var(--gold-deep); }

.btn--light {
  background: var(--bg);
  color: var(--ink);
}

.btn--light:hover,
.btn--light:focus-visible { background: var(--white); }

:where(a, button):focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

@media (max-width: 767px) {
  .btn { padding-inline: var(--space-32); width: 100%; max-width: 320px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* Breakpoint image swaps are wrapped in <picture>. The wrapper must never
   take part in layout — with a box of its own it becomes the image’s
   offset parent and the image’s coordinates resolve against the wrapper
   instead of the section. display: contents removes the box entirely.
   Note this does NOT help selectors: a rule written `section > *` still
   fails to reach an <img> inside a <picture>, so any such rule has to name
   `> picture > img` as well (see blog.css / membership.css / event.css). */
picture { display: contents; }

/* ==========================================================================
   Click-through for stacked sections (2026-07-21)
   ==========================================================================
   Most ported pages stack their sections at top:0 at full height, so a later
   section's transparent box lies OVER the earlier sections and silently
   blocks clicks to their CTAs and links — every position measurement passes
   because the buttons are exactly where they belong, they simply cannot be
   reached (elementFromPoint returns the covering section). This was found and
   fixed on consultation; the same shape is on blog, article, program,
   programs, team, cart, event and more.

   The section box is made transparent to pointer events and the children take
   them back. pointer-events inherits, so the whole subtree of every direct
   child is clickable, while the section's own empty area passes clicks
   through to whatever it covers. Nothing about layout or geometry changes. */
main > section { pointer-events: none; }
main > section > * { pointer-events: auto; }

/* Decorative overlays (aria-hidden) must never intercept a click. Several are
   direct children of a section — a full-cover line pattern on the cart, page
   backgrounds, rings — and the click-through rule above hands section children
   pointer events, which would let those decoratives block the buttons beneath
   them (cart's stepper, Apply and checkout were caught this way). They carry
   no interactive descendants, so switching them off is always safe. */
main [aria-hidden="true"] { pointer-events: none; }
