/*
 * PROVENANCE — NOT A LIBRARY COPY. Authored here, and staying here.
 * ─────────────────────────────────────────────────────────────────────────
 * Entry            menu-overlay          (name ruled 2026-09-03)
 * Entry version    —  no library entry exists, by ruling
 * Source           authored at gravitystack-main, mobile menu build
 * SHA-256          —  nothing has been pulled
 * Pulled           —
 * Substrate        base.css, rule 4e "A custom overlay needs a height chain"
 *                  and section 3 "Buttons inside a navigation block". Both
 *                  are required. Without 4e the panel renders and the close
 *                  control scrolls off screen, which does not error. The
 *                  "Menu organism substrate" rules 4a-4d are NOT a
 *                  dependency — they are scoped to >=600px and to the closed
 *                  state, and this organism only exists below 600px
 * Specificity      no record needed yet; nothing here doubles a class
 *
 * ── WHY THERE IS NO LIBRARY ENTRY, AND WHY THAT IS THE RULING ────────────
 * One site has this. `library/menus/` names entries `[form]-[organiser]`
 * where form is `mega` or `dropdown`, and both carry a HEADER positioning
 * difference — a mega positions against the header, a dropdown hangs under
 * its item. A custom overlay is neither: core positions it `fixed; inset: 0`
 * against the viewport, so the category's rule genuinely cannot name it.
 *
 * That is a naming-rule question for a category that does not need to exist
 * until a second site needs the entry. **First instance stays in the theme.**
 * Ruled 2026-09-03. Nothing is extracted, so there is no version and no hash
 * above — the four-way re-pull table has nothing to decide between.
 *
 * ── WHY `menu-overlay` AND NOT `overlay-disclosure` ──────────────────────
 * The disclosure is one behaviour inside the object, not the object itself.
 * A site whose overlay carried a flat list would make `overlay-disclosure` a
 * lie while the object stayed the same thing. `menu-overlay` names the
 * object, and it sits inside core's own vocabulary — which matters for an
 * organism this close to substrate, where a reader is holding core's class
 * names in mind at the same time.
 * ─────────────────────────────────────────────────────────────────────────
 */
/*
 * menu-overlay.css — the mobile menu overlay, design layer.
 *
 * The blocks in `parts/navigation-overlay.html`, rendered by core inside
 * `.wp-block-navigation__overlay-container` when the nav block's `overlay`
 * attribute resolves. Below 600px only — core's `overlayMenu: mobile`
 * threshold, which is where the responsive container exists at all.
 *
 * ── WHAT CORE GIVES, AND WHAT IT TAKES BACK ──────────────────────────────
 * Verified on the render 2026-09-03, gate record in
 * docs/verification/mobile-menu-overlay-gate-2026-09-03/.
 *
 * Core supplies, unconditionally: `position: fixed; inset: 0`, `z-index:
 * 100000`, `overflow: auto`, and `display: flex; flex-direction: column` on
 * the open container. It also hides the desktop `<ul>` for us and wires the
 * close block's behaviour and focus return.
 *
 * Core WITHDRAWS, the moment `disable-default-overlay` is present: the
 * background fill, the text colour, the padding, and the content layout.
 * Those four are gated behind `:not(.disable-default-overlay)` in core's own
 * stylesheet. **So the open overlay is transparent until this file paints
 * it** — the page reads straight through, which is what the gate capture
 * shows. The fill below is therefore load-bearing, not decoration.
 *
 * ── SCOPING ──────────────────────────────────────────────────────────────
 * One query wraps the whole file, and it carries TWO conditions:
 * `(max-width: 599.98px), (max-height: 499.98px)`. The first is core's
 * `overlayMenu` threshold, not a layout decision of ours — the same raw
 * value and the same reasoning as `base.css` rules 2e and 4a, which record
 * the deviation from the two canonical breakpoints in full. **This is the
 * third rule at 600px and the build index says a third makes 600px a de
 * facto breakpoint no standard names.** Flagged, not silently taken; the
 * debt is owed to `gravitysite-css-standards.md`.
 *
 * The second condition is the SHORT-VIEWPORT SWITCH, added 2026-09-04 at
 * 4.33.0. A landscape phone is wide enough for the desktop nav and far too
 * short for the mega panel it opens — measured at 915x412: a 666px panel in
 * a 288px slot below a 124px header, 377px of it below the fold and no
 * scroll that reaches it, because the header is sticky and the panel is
 * absolute inside it. This organism is the arrangement that already handles
 * a short box — rule 4e pins the bar and scrolls the tree — so the fix is
 * to route that viewport here rather than to teach the mega panel to
 * shrink. **The authority for the 500px threshold and for the height axis
 * itself is `base.css` rule 4g. It is not restated here.**
 *
 * The two conditions are a comma, not an `and`: either one alone routes to
 * this organism. A narrow tall phone meets the first, a wide short phone
 * the second, and a small phone in landscape meets both.
 *
 * `max-width` rather than this file's mobile-first default, deliberately and
 * for base.css rule 2e's reason: the mobile-first form would need every
 * declaration below unwound above 600px, where the overlay container is
 * `display: none` anyway and none of it applies.
 *
 * ── TOKENS ───────────────────────────────────────────────────────────────
 * Every colour, size, space, and radius resolves through theme.json. Two
 * channels, as on the desktop panel: the palette for `gravity-*`, and the
 * primitive scale in `settings.custom.color` for `brand-11`, `brand-12`,
 * `neutral-6`, and `neutral-9`, which have no palette slug.
 *
 * Contrast, measured 2026-09-03 against the actual surfaces:
 *   gravity-text on gravity-surface-nested ........ 14.06:1   headline, subline
 *   gravity-text-muted on gravity-surface-nested ..  5.13:1   eyebrow
 *   brand-12 on gravity-surface-nested ............  9.47:1   band link
 *   gravity-text on white ......................... 16.32:1   rows
 *   gravity-text-muted on white ...................  5.96:1   cell names
 *   neutral-9 on white ............................  3.34:1   chevron, passes 3:1
 *   brand-11 on white .............................  4.81:1   current-page bar
 *   neutral-6 on white ............................  1.41:1   row rules
 *
 * `neutral-9` reads **2.88:1 on the tint** and fails the non-text floor
 * there, which is why no chevron sits on the band. `neutral-6` is
 * decoration under section 5's edge test — the rows are already separated by
 * spacing and the rule only refines it — so 1.41:1 is exempt rather than a
 * breach.
 */

@media (max-width: 599.98px), (max-height: 499.98px) { /* core's overlayMenu threshold, or a short viewport — see the scoping note */

/* a. The surface core stops supplying.
 *
 * The overlay container is core's; this paints it. `background-color` on the
 * container rather than on `.c-menu-overlay` because core sets `background-color:
 * inherit` on the open container, so a fill on our own wrapper would leave
 * the container's own box — the part above and below the wrapper's content —
 * transparent during overscroll.
 */
.wp-block-navigation__responsive-container.disable-default-overlay.is-menu-open {
  background-color: var(--wp--preset--color--gravity-surface);
  color: var(--wp--preset--color--gravity-text);
}

/* b. The overlay's own frame. The identity bar is pinned and the tree
 * scrolls beneath it, so a long panel never takes the close control off
 * screen with it. Core's `overflow: auto` on the container is left alone and
 * the scrolling is done one level in, which is what keeps the bar still.
 */
.c-menu-overlay {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-block-size: 0;
}

/* b-iii. The overlay's identity bar is a SECOND identity, and it must not
 * read as the first one moving.
 *
 * Core's responsive container is `fixed; inset: 0`, so the open overlay
 * covers the real header row completely. Nothing shrinks or shifts — one
 * element is swapped for a slightly different one, and the eye reads the
 * difference as movement. Three things could differ; measured on the render
 * at probe4, only two did.
 *
 * LOGO WIDTH — mismatched, 160px against the row's 200px. Fixed below by
 * reading `--c-header-logo-width`, the same custom property `base.css` rule
 * 2a publishes and `.c-header__logo img` consumes. Both bars now read one
 * source, so they are the same size by construction rather than by two
 * people picking the same number. The block's inline width attribute was
 * removed for the same reason — a value in the markup cannot track a token.
 *
 * ROW HEIGHT — **not** mismatched, and this is worth stating so it is not
 * "fixed" later. Both boxes measure 77px, and they do so by the same
 * construction: `spacing|30` block padding around a 44px control. The
 * header row's 44px comes from its toggle, this bar's from its close
 * control. Nothing to change.
 *
 * THE EDGE — see rule b-iv.
 */
.c-menu-overlay__top {
  flex: 0 0 auto;
  padding-block: var(--wp--preset--spacing--30);
  padding-inline: var(--wp--preset--spacing--40);
  border-block-end: 1px solid var(--wp--custom--color--neutral-9);
}

.c-menu-overlay__logo img {
  width: var(--c-header-logo-width);
  height: auto;
}

/* b-iv. The bar's edge is a raised edge, and the 3:1 bar binds.
 *
 * ESTABLISHED ON THE RENDER BEFORE THE COLOUR WAS SET, because the argument
 * depends on it. Rule 4e pins this bar and scrolls the tree beneath it, but
 * the panel had been short enough in every screenshot that the pin had never
 * actually been demonstrated. Forced tall at probe4: the scroll region
 * reported 976px of content in a 707px box, the bar held at y=9 while the
 * tree scrolled 269px under it, and the container itself did not scroll.
 * **The bar is genuinely pinned with content passing under it.**
 *
 * That is section 5's raised-edge case exactly — an edge that is the sole
 * thing separating a surface from what sits behind it, rather than one
 * refining a separation already carried by fill, shadow, or spacing. Both
 * surfaces here are `gravity-surface` `#ffffff`, so nothing else separates
 * them. The edge meets 3:1.
 *
 * `neutral-9` `#898e87` at **3.34:1**, which is the same value and the same
 * channel `base.css` uses for the header's own raised edge. The open menu is
 * therefore consistent with the stuck header instead of inventing a third
 * edge treatment. It is NOT removed: at rest the header row's edge is
 * transparent and exempt because spacing carries the separation, and this
 * bar is never at rest — it exists only in the pinned state.
 *
 * The reasoning for the channel rather than a palette token is in `base.css`
 * under the raised edge and is not restated here.
 */

.c-menu-overlay__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
}

/* b-ii. The gutters, qualified because Spectra forces it.
 *
 * Spectra One's `style.min.css` carries
 * `.wp-block-group.is-layout-flow.wp-block-group-is-layout-flow { padding: 0 }`
 * at (0,3,0). Every `core/group` in this part that uses flow layout matches
 * it, so a single-class padding rule here computed to `0px` and the panel
 * rendered flush to the viewport edge on both states — the identity bar
 * survived only because it is `is-layout-flex` and that selector does not
 * reach it.
 *
 * `gravitysite-css-standards.md` sanctions qualifying with block classes
 * exactly here — "only when Spectra forces it, and comment why". The chain is
 * matched in full plus our own class, which is (0,4,0) and therefore does not
 * depend on load order; this file already loads after Spectra's, and relying
 * on that alone would put the gutters one enqueue change away from vanishing.
 *
 * DECLARATION IS DESIGN, NOT SUBSTRATE. What it declares is the panel's
 * gutter, which is what the design says; the high specificity is the cost of
 * landing it rather than the reason it exists. That is the test in the CSS
 * standard that keeps this in the organism file instead of `base.css`.
 */
.c-menu-overlay__scroll.wp-block-group.is-layout-flow.wp-block-group-is-layout-flow {
  padding-block: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
  padding-inline: var(--wp--preset--spacing--40);
}

/* c. The close control. Core ships it at 24px, which is under the floor.
 * The container is enlarged, never the glyph — the glyph is core's and is
 * sized to the rest of the system.
 */
.c-menu-overlay__close {
  min-block-size: 44px;
  min-inline-size: 44px;
  padding-inline: var(--wp--preset--spacing--20);
  margin-inline-end: calc(var(--wp--preset--spacing--20) * -1);
  font-size: var(--wp--preset--font-size--text-2);
  font-weight: var(--wp--custom--weight--strong);
  color: var(--wp--preset--color--gravity-text);
  border-radius: var(--wp--custom--rounded--sm);
}

/* d. The action, first object in the tree.
 *
 * The header's two-line enhancement, restated as a panel-width object. The
 * label and meta treatment comes from `base.css` rule 2b.
 *
 * THE WIDTH IS CORE'S, NOT OURS. The block carries
 * `has-custom-width wp-block-button__width-100`, and core's own button
 * stylesheet does the rest — `width: 100%; flex-basis: 100%` on the wrapper,
 * `width: 100%` on the link, plus `text-align: center` and `align-content:
 * center` from its base rule, which is what keeps the two-line label centred
 * and vertically even once the box widens. Reimplementing any of that here
 * would drift from what the editor shows, so this rule declares only what
 * core does not: the inset, the radius, and the target floor.
 *
 * On WordPress 7.1 the button's width is a `dimensions.width` SUPPORT rather
 * than the older bespoke `width` attribute — `core/button`'s block.json
 * carries no `width` attribute at all. The classes above are still what
 * core's shipped CSS keys on, and `core/button` is a static block, so the
 * saved markup is authoritative on the front end. Read from the live
 * install's block.json and style.css, 2026-09-03.
 */
.c-menu-overlay__action .wp-block-button__link {
  min-block-size: 44px;
  padding: 14px var(--wp--preset--spacing--40);
  border-radius: var(--wp--custom--rounded--lg);
}

/* e. The tree's rows. Two objects share this treatment — the disclosure's
 * `<summary>` and each item in the nested navigation block — so that the
 * four rows read as one list rather than as a widget above a menu. They are
 * separate blocks because core cannot put a `details` inside a navigation
 * block's list; the rule is what makes the seam invisible.
 *
 * `box-sizing` IS LOAD-BEARING, AND THAT IS THE WHOLE OF THE FIRST DEFECT
 * FIXED 2026-09-04. The two objects did not agree on what `min-block-size:
 * 52px` measured. `<summary>` computes `box-sizing: content-box` — it is
 * outside the reach of the border-box reset that covers the rest of the
 * page — so 52px was its CONTENT box and the 10px padding pair sat outside
 * it: **72px**. The navigation item's anchor is `border-box`, so the same
 * declaration gave a 52px total. Measured on the live render at 390x844,
 * closed: rows of 72 / 52.8 / 52.8 / 52.8. The one-list intent above was
 * defeated by a box model, not by a spacing value, which is why no amount
 * of adjusting `padding-block` would have found it.
 *
 * Declared on the shared rule rather than patched onto `summary` alone: the
 * row's box model is a property of the row, and both objects claiming it
 * from one place is what stops the next reader fixing one of them.
 */
.c-menu-overlay__disc > summary,
.c-menu-overlay__links .wp-block-navigation-item__content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--wp--preset--spacing--30);
  box-sizing: border-box;
  min-block-size: 52px;
  padding-block: 10px;
  font-size: var(--wp--preset--font-size--text-3);
  font-weight: var(--wp--custom--weight--strong);
  color: var(--wp--preset--color--gravity-text);
  text-decoration: none;
  cursor: pointer;
}

.c-menu-overlay__disc,
.c-menu-overlay__links .wp-block-navigation-item {
  border-block-end: 1px solid var(--wp--custom--color--neutral-6);
}

.c-menu-overlay__disc {
  margin-block-start: var(--wp--preset--spacing--40);
  border-block-start: 1px solid var(--wp--custom--color--neutral-6);
}

/* The nested navigation block is a plain vertical list here. The `display`
 * reset that stops core's flex layout shrink-wrapping the list is substrate
 * and lives in `base.css` rule 4f; what is left here is the gap, which is
 * rhythm and therefore design — the rows carry their own spacing.
 *
 * TWO gaps, and only one of them was declared. `gap: 0` handles the space
 * BETWEEN the navigation items. The space between the disclosure and the
 * navigation block is a different mechanism entirely: both are children of
 * `.c-menu-overlay__scroll`, which is flow layout, so core's
 * `:where(.is-layout-flow) > * + *` gave the nav block
 * `margin-block-start: var(--wp--style--block-gap)` — **24px**, measured on
 * the live render at 390x844. That is the second defect fixed 2026-09-04
 * and it is what put a visible band under "How We Help" while the three
 * rows below it sat flush.
 *
 * Zeroed rather than tuned. The rows are contiguous by design — rule e
 * exists to make the seam between the two blocks invisible — and a
 * block-gap between them is the seam showing. The disclosure's own
 * `margin-block-start` above is a separate and deliberate declaration: it
 * separates the tree from the action, which is a real division.
 *
 * Core's selector is `:where()`-wrapped and therefore zero specificity, so
 * a single class settles it with nothing escalated.
 */
.c-menu-overlay__links {
  margin-block-start: 0;
}

.c-menu-overlay__links .wp-block-navigation__container {
  gap: 0;
}

.c-menu-overlay__links .wp-block-navigation-item {
  display: block;
}

/* f. The disclosure marker. Core draws its own triangle on `summary`; it is
 * replaced rather than restyled, because the marker is a UA-drawn glyph with
 * no colour or size control worth having. The chevron is `neutral-9` at
 * 3.34:1 on white — over the 3:1 non-text floor, and the reason no chevron
 * is ever drawn on the tint band, where the same value reads 2.88:1.
 */
.c-menu-overlay__disc > summary {
  list-style: none;
}

.c-menu-overlay__disc > summary::-webkit-details-marker {
  display: none;
}

.c-menu-overlay__disc > summary::after {
  content: "";
  flex: 0 0 10px;
  inline-size: 10px;
  block-size: 10px;
  border-inline-end: 2px solid var(--wp--custom--color--neutral-9);
  border-block-end: 2px solid var(--wp--custom--color--neutral-9);
  transform: translateY(-25%) rotate(45deg);
  transition: transform 180ms ease-out;
}

.c-menu-overlay__disc[open] > summary::after {
  transform: translateY(25%) rotate(225deg);
}

/* g. The current page, marked twice — a colour shift on the label and a bar
 * in the gutter. Two indicators rather than one because colour alone is not
 * a distinction under the floor, and the bar alone is easy to miss on a
 * narrow screen. `aria-current` is core's, emitted by the navigation block.
 *
 * The bar sits in the scroll region's inset rather than beside the label, so
 * it reads as an edge marker on the row rather than as a bullet.
 */
.c-menu-overlay__links .wp-block-navigation-item:has(> [aria-current="page"]) {
  position: relative;
}

.c-menu-overlay__links [aria-current="page"] {
  color: var(--wp--custom--color--brand-12);
}

.c-menu-overlay__links .wp-block-navigation-item:has(> [aria-current="page"])::before {
  content: "";
  position: absolute;
  inset-inline-start: calc(var(--wp--preset--spacing--40) * -1);
  inset-block: 10px;
  inline-size: 3px;
  border-radius: 2px;
  background-color: var(--wp--custom--color--brand-11);
}

/* h. The flagship band. Four slots, the same order and the same colour
 * assignment as the desktop panel: charcoal for headline and subline, muted
 * for the eyebrow, `brand-12` for the link alone.
 *
 * The subline is the reason this whole organism is a disclosure rather than
 * an open list — it carries the Quarterly Proof guarantee, it may not be
 * cut, and it is what takes the band to roughly 250px. See the mockup's
 * header comment and the build index.
 */
.c-menu-overlay__band {
  background-color: var(--wp--preset--color--gravity-surface-nested);
  border-radius: var(--wp--custom--rounded--md);
  margin-block: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
}

/* The band's inset meets the same Spectra rule as the scroll region above,
 * and for the same reason it is qualified rather than escalated arbitrarily.
 * Without it the tint band paints edge to edge with its text on the viewport
 * boundary, which is how it rendered at probe3.
 */
.c-menu-overlay__band.wp-block-group.is-layout-flow.wp-block-group-is-layout-flow {
  padding: var(--wp--preset--spacing--30);
}

.c-menu-overlay__eyebrow {
  font-size: var(--wp--preset--font-size--text-1);
  font-weight: var(--wp--custom--weight--strong);
  letter-spacing: var(--wp--custom--tracking--wide);
  text-transform: uppercase;
  color: var(--wp--preset--color--gravity-text-muted);
  margin: 0 0 6px;
}

.c-menu-overlay__headline {
  font-family: var(--wp--preset--font-family--outfit);
  font-size: var(--wp--preset--font-size--text-3);
  font-weight: var(--wp--custom--weight--strong);
  line-height: 1.3;
  color: var(--wp--preset--color--gravity-text);
  margin: 0 0 var(--wp--preset--spacing--20);
}

.c-menu-overlay__subline {
  font-size: var(--wp--preset--font-size--text-2);
  line-height: 1.5;
  color: var(--wp--preset--color--gravity-text);
  margin: 0 0 var(--wp--preset--spacing--30);
}

.c-menu-overlay__flink {
  margin: 0;
}

.c-menu-overlay__flink a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-block-size: 44px;
  font-size: var(--wp--preset--font-size--text-2);
  font-weight: var(--wp--custom--weight--strong);
  color: var(--wp--custom--color--brand-12);
  text-decoration: none;
}

.c-menu-overlay__arw {
  font-size: var(--wp--preset--font-size--text-3);
}

/* i. The service cells. The promise leads and the name attaches beneath —
 * `gravitysite-header-standards.md` section 2's promise-first branch, which
 * applies because a buyer does not search these product names. Order is
 * Know / Stop / Get and is a sequence, not a sort.
 */
.c-menu-overlay__svc {
  margin: 0;
}

.c-menu-overlay__svc a {
  display: block;
  padding-block: 10px;
  min-block-size: 44px;
  color: var(--wp--preset--color--gravity-text);
  text-decoration: none;
}

.c-menu-overlay__promise {
  display: block;
  font-size: var(--wp--preset--font-size--text-2);
  font-weight: var(--wp--custom--weight--strong);
  line-height: 1.35;
}

.c-menu-overlay__name {
  display: block;
  font-size: var(--wp--preset--font-size--text-1);
  color: var(--wp--preset--color--gravity-text-muted);
  margin-block-start: 1px;
}

/* j. The foot strip. One link, no label, no arrow — the arrow stays the
 * flagship link's affordance. The only draft line in the panel.
 */
.c-menu-overlay__foot {
  margin: var(--wp--preset--spacing--20) 0 var(--wp--preset--spacing--30);
}

.c-menu-overlay__foot a {
  display: block;
  padding-block: 10px;
  min-block-size: 44px;
  font-size: var(--wp--preset--font-size--text-2);
  font-weight: var(--wp--custom--weight--strong);
  color: var(--wp--preset--color--gravity-link);
  text-decoration: none;
}

} /* end (max-width: 599.98px), (max-height: 499.98px) */

/* k. Reduced motion. The chevron is the only thing here that moves; the
 * overlay's own arrival is core's display toggle and cannot be transitioned.
 * Outside the width query deliberately — an OS preference is not scoped to a
 * viewport, and `gravitysite-css-standards.md` files reduced motion as one
 * of the page-level decisions viewport queries are reserved for.
 */
@media (prefers-reduced-motion: reduce) {
  .c-menu-overlay__disc > summary::after {
    transition: none;
  }
}
