/* FormsPal shared-frame token map (property-owned). The vendored frame
   reads --fp-* and follows the page theme via the data-theme bridge in
   theme-boot.js. CTA keeps the ai property's dark-green button voice. */
:root {
  --fp-header-h: 64px;
  --fp-bg: var(--bg);
  --fp-ink: var(--ink);
  --fp-green: var(--primary);
  --fp-green-soft: var(--primary-dark);
  --fp-orange: var(--btn);
  --fp-orange-hover: var(--primary-dark);
  --fp-orange-ink: #ffffff;
}


/* fp-shared-frame:start (vendored css; update via scripts/sync-shared-frame.sh) */
/* FormsPal shared header. Scope everything under .site-head (plus :root/html
   for variables and the no-JS fallback). Fleet look: dark-first, green
   primary, orange CTA. Properties override the --fp-* variables. */

/* The sticky bar would otherwise cover whatever a keyboard Tab or an anchor
   jump scrolls to the top of the viewport (WCAG 2.2 SC 2.4.11). */
html {
  scroll-padding-top: calc(var(--fp-header-h, 64px) + 8px);
}

:root {
  --fp-header-h: 64px;
  --fp-ease: cubic-bezier(0.2, 0, 0, 1);
  --fp-dur: 150ms;
}

.site-head {
  position: sticky;
  top: 0;
  z-index: 50;
  /* min-height, not height: if the measured collapse ever fails to fire, a
     wrapped nav grows the bar instead of overlapping the page beneath it.
     Content never exceeds 44px plus padding in the normal case, so the
     rendered height stays 64px and CLS is unchanged. */
  min-height: var(--fp-header-h);
  background: var(--fp-bg, #0b1f17);
  color: var(--fp-ink, #eaf5ef);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  --fp-head-soft: color-mix(in oklab, var(--fp-ink, #eaf5ef) 82%, var(--fp-bg, #0b1f17));
  --fp-head-muted: color-mix(in oklab, var(--fp-ink, #eaf5ef) 70%, var(--fp-bg, #0b1f17));
}
html[data-theme="light"] .site-head {
  background: var(--fp-bg, #f4faf7);
  color: var(--fp-ink, #10231a);
  border-bottom-color: rgba(0, 0, 0, 0.08);
  --fp-head-soft: color-mix(in oklab, var(--fp-ink, #10231a) 82%, var(--fp-bg, #f4faf7));
  --fp-head-muted: color-mix(in oklab, var(--fp-ink, #10231a) 70%, var(--fp-bg, #f4faf7));
}

/* The frame owns the box model of its own padded controls. Every control
   that combines padding with a 44px floor would otherwise render at
   44 + padding wherever the host page ships no reset: measured on a page
   with none, .site-cta, .site-nav a and .site-drop-list a all came out at
   60px instead of 44. Five properties ship a global reset, but
   formspal-legal-tools scopes its own to `.lp *` and `.dc-app *` and the
   frame sits at body level outside both, so the same markup rendered two
   different bars across the fleet. It is also latent breakage: the
   collapsed panel is positioned at top: var(--fp-header-h), so a property
   that lowered that token would grow the bar past it while the panel
   stayed put. <button> already gets border-box from the UA sheet; the
   anchors do not, and the frame should not depend on either.

   .site-nav-wrap is in this list for the same reason at a different scale.
   It is not a 44px control, but it is the one box here where padding meets
   a viewport-relative bound: collapsed, it carries
   max-height: calc(100vh - var(--fp-header-h)) together with
   padding: 8px 16px 16px. Under content-box those add rather than nest, so
   the panel's border box is the max-height plus 24px of padding plus its
   1px border. Measured at 700x600 the collapsed panel's bottom landed at
   625 against a 600px viewport, 25px past the fold, and the overshoot is
   the part holding the last row of links. Border-box makes the bound mean
   what it says. This one predates the 44px floors and is identical in
   v0.7.1, but the rule above claims the frame owns the box model of its own
   padded boxes, and this is the box where the claim pays. */
.site-head .site-cta,
.site-head .site-nav a,
.site-head .site-drop-btn,
.site-head .site-menu-btn,
.site-head .site-drop-list a,
.site-head .site-drop-list span[aria-current],
.site-head .site-nav-wrap,
/* The frame's own layout containers must not inherit the host page's box model.
   A property whose reset is scoped (e.g. `.lp * { box-sizing: border-box }`)
   leaves these in content-box, where max-width applies to the CONTENT box and
   the 16px padding is added on top: the bar then renders 32px wider than the
   footer's matching 1120px container and the two land on different edges. */
.site-head-inner {
  box-sizing: border-box;
}

.site-head-inner {
  max-width: 1120px;
  min-height: var(--fp-header-h);
  margin: 0 auto;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.site-head .site-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  /* 44px floor: Apple HIG's default control size, and WCAG 2.5.5 AAA. The
     64px bar absorbs a 44px control with no change to its own height.
     min-width is deliberately NOT set here: on a flex item it would replace
     the automatic minimum size (min-width: auto, i.e. min-content) and let
     the brand be squeezed below its own nowrap content. Measured at 480px
     with the app name "Statute of Limitations", a 44px floor gave an 85px
     box around 202.6px of content: the trailing text ran out over the
     hamburger and, with justify-content: center, the logo mark clipped off
     the left edge. The floor is needed only below 430px, where the wordmark
     and app name are both hidden and the 28px mark alone would be the whole
     target, so it lives in that breakpoint with the centering it needs. */
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  font-size: 17px;
  white-space: nowrap;
}
.site-head .site-brand svg { width: 28px; height: 28px; flex: none; }
.site-head .site-brand .app {
  color: var(--fp-head-soft);
  font-weight: 500;
}

.site-head .site-nav-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.site-head .site-dropdown { position: relative; }

.site-head .site-drop-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 4px;
  font: inherit;
  font-size: 14px;
  color: inherit;
  background: none;
  border: 0;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.site-head .site-drop-btn:hover,
.site-head .site-drop-btn[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.08);
}
html[data-theme="light"] .site-head .site-drop-btn:hover,
html[data-theme="light"] .site-head .site-drop-btn[aria-expanded="true"] {
  background: rgba(0, 0, 0, 0.06);
}
.site-head .site-drop-btn .caret { width: 14px; height: 14px; }

.site-head .site-drop-list {
  list-style: none;
  margin: 0;
  padding: 6px;
}
.site-head .site-drop-list a,
.site-head .site-drop-list span[aria-current] {
  display: block;
  padding: 8px 12px;
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
  font-size: 14px;
  white-space: nowrap;
}
.site-head .site-drop-list a:hover {
  background: var(--fp-green, #0e8a5f);
  color: #fff;
}
.site-head .site-drop-list span[aria-current] { color: var(--fp-head-muted); }

/* JS-enabled: dropdowns collapse into popovers. Without the fp-js class
   (JS disabled or failed) the lists stay in normal flow, fully visible. */
html.fp-js .site-head .site-drop-list {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 230px;
  background: var(--fp-bg, #0e2a1f);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}
html[data-theme="light"].fp-js .site-head .site-drop-list {
  background: var(--fp-bg, #ffffff);
  border-color: rgba(0, 0, 0, 0.1);
}
html.fp-js .site-head .site-dropdown.open .site-drop-list { display: block; }

.site-head .site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  /* Never overflow: hidden here. It converts "does not fit" into "silently
     disappears": measured at 768px the nav wanted 244px, got 79px, and lost
     two links entirely with no scrollbar to hint at it. header.js decides
     fit now. Wrapping is the visible, debuggable fallback. */
  flex-wrap: wrap;
}
.site-head .site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 8px;
  white-space: nowrap;
}
.site-head .site-nav a:hover { background: rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-head .site-nav a:hover { background: rgba(0, 0, 0, 0.06); }

.site-head .site-right {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex: none;
}

.site-head .site-menu-btn {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  color: inherit;
  background: none;
  border: 0;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
  margin-left: auto;
}
.site-head .site-menu-btn svg { width: 22px; height: 22px; display: block; }

/* No-JS fallback (all widths): without the fp-js class the dropdown lists
   stay in normal flow as plain visible link lists, so the bar can no longer
   hold a fixed height. It grows instead, and the nav wraps to its own full
   width row below the brand, which itself stacks when it runs out of width.
   The hamburger never appears without JS, so nothing here may be gated on
   the collapse class: only header.js sets it. This path is not the rare
   one it sounds like. ocr-web and pdf-extension both load header.js with
   defer, against the documented contract, so it is what paints on every
   page load there until the script runs. */
html:not(.fp-js) .site-head {
  height: auto;
  min-height: var(--fp-header-h);
}
html:not(.fp-js) .site-head .site-head-inner {
  flex-wrap: wrap;
  height: auto;
  padding: 8px 16px;
}
html:not(.fp-js) .site-head .site-nav-wrap {
  flex-basis: 100%;
  /* The panel has to stack here, not under html.fp-nav-collapsed. Only
     header.js ever sets that class, so with no script the wrap stayed a
     single unwrapped row: measured at 375px with fp-js absent, the document
     was 527px wide against a 375px viewport, and the wrap itself 511px
     inside a 343px box. That is the reflow failure (WCAG 1.4.10, measured
     at 320px) the 719px media block used to cover, because it applied
     whether or not fp-js was present.

     Wrapping rather than an unconditional column, and rather than a second
     breakpoint: nothing without JS can measure fit, and the fit point is
     property-owned (nav copy, page-nav slot). Wrap answers it from the
     content at every width. The groups sit side by side while they fit
     (at 1280px the no-JS bar is still the same single row it was) and
     stack when they do not, which is what the removed block did below
     719px. */
  flex-wrap: wrap;
  /* Bounded like the JS panel: without this the stacked groups make a
     header taller than the phone showing it. */
  max-height: calc(100vh - var(--fp-header-h));
  overflow: auto;
}
html:not(.fp-js) .site-head .site-menu-btn {
  display: none;
}

/* Collapsed: one hamburger; dropdown groups and page nav stack in a panel.
   Height stays fixed and the panel overlays below the bar (no CLS).

   Driven by a class rather than a width because the fit point is not a
   constant. It moves with the nav copy, the CTA label, and anything a
   property puts in .site-right, including the plan pill that only appears
   after sign-in. header.js sets this class from a real measurement. */
html.fp-nav-collapsed .site-head .site-menu-btn { display: inline-flex; }
html.fp-nav-collapsed .site-head .site-nav-wrap {
  display: none;
  position: absolute;
  top: var(--fp-header-h);
  left: 0;
  right: 0;
  flex-direction: column;
  align-items: stretch;
  background: var(--fp-bg, #0b1f17);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  padding: 8px 16px 16px;
  max-height: calc(100vh - var(--fp-header-h));
  overflow: auto;
}
html[data-theme="light"].fp-nav-collapsed .site-head .site-nav-wrap { background: var(--fp-bg, #f4faf7); }
html.fp-nav-collapsed .site-head.menu-open .site-nav-wrap { display: flex; }
html.fp-js.fp-nav-collapsed .site-head .site-drop-list,
html.fp-js.fp-nav-collapsed .site-head .site-dropdown.open .site-drop-list {
  position: static;
  display: block;
  min-width: 0;
  border: 0;
  box-shadow: none;
  background: none;
}
html.fp-nav-collapsed .site-head .site-drop-btn { pointer-events: none; }
html.fp-nav-collapsed .site-head .site-drop-btn .caret { display: none; }
html.fp-nav-collapsed .site-head .site-nav { flex-direction: column; align-items: stretch; }
/* There is deliberately no html:not(.fp-js).fp-nav-collapsed rule here.
   header.js adds fp-js at execute time and fp-nav-collapsed only after
   that, so the combination cannot occur and any rule written for it is
   dead code that reads like the no-JS fallback while doing nothing. The
   no-JS layout lives in one place, the html:not(.fp-js) block above. */

/* The hamburger belongs with the other controls, not adrift mid bar.
   .site-menu-btn and .site-right both carry margin-left: auto, and flexbox
   splits the free space between two auto margins: measured at 768px the
   brand ended at x=171.9, the hamburger sat at x=284.6 and the right
   cluster started at x=441.2, leaving 92.6px of dead space on each side.
   Dropping the right cluster's auto margin while collapsed hands all the
   free space to the hamburger's own, so the bar reads the way it does
   expanded: brand left, controls right. Scoped to the collapsed state
   because .site-right's auto margin is what right-aligns the cluster when
   the nav is a normal flex item.

   The coupling this creates: while collapsed, .site-right is right-aligned
   only because the hamburger's auto margin is still in the row absorbing
   the free space. Take the button out of the markup, or have a property
   force it display: none while collapsed, and nothing pushes: the cluster
   slides left from x=441.2 to x=191.9 and sits mid bar. No property in the
   fleet does either today, and the frame ships the button in header.html,
   so this is a note for whoever changes that, not a live bug. */
html.fp-nav-collapsed .site-head .site-right { margin-left: 0; }

/* Hallmark · component: header right-side controls · genre: modern-minimal
 * theme: FormsPal fleet tokens (--fp-*)
 * states: default · hover · focus-visible · active (loading/error/success N/A for nav)
 * Right-side controls: shared base styles. Properties may override, but the
 * bar ships finished. */

.site-head .site-drop-btn .caret {
  transition: transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-drop-btn[aria-expanded="true"] .caret {
  transform: rotate(180deg);
}

.site-head .site-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background-color var(--fp-dur) var(--fp-ease);
}
.site-head .site-theme-toggle svg {
  width: 18px;
  height: 18px;
  display: block;
  stroke: currentColor;
}
.site-head .site-theme-toggle .moon { display: none; }
html[data-theme="light"] .site-head .site-theme-toggle .sun { display: none; }
html[data-theme="light"] .site-head .site-theme-toggle .moon { display: block; }
.site-head .site-theme-toggle:hover { background: rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-head .site-theme-toggle:hover { background: rgba(0, 0, 0, 0.06); }
.site-head .site-theme-toggle:active { transform: translateY(1px); }

.site-head .site-cta {
  display: inline-flex;
  align-items: center;
  /* The frame owns this button's box, so it owns the containing block for
     anything a property decorates it with. Two properties add a ::after gleam
     that sweeps on hover, sized in percentages. Without position: relative
     those percentages resolved against .site-head, which is sticky and
     therefore the nearest positioned ancestor: the gleam came out 630px wide
     and 64px tall on a 150x44 button, and swept the full width of the bar.
     overflow: hidden then keeps it inside the rounded rect. Harmless for
     properties that add no decoration. */
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 10px;
  background: var(--fp-orange, #ef8b2d);
  color: var(--fp-orange-ink, #1c1206);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--fp-dur) var(--fp-ease), transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-cta:hover { background: var(--fp-orange-hover, #f79c47); }
.site-head .site-cta:active { transform: translateY(1px); }

.site-head .site-theme-toggle:focus-visible,
.site-head .site-cta:focus-visible,
.site-head .site-drop-btn:focus-visible,
.site-head .site-menu-btn:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .site-head .site-drop-btn .caret,
  .site-head .site-theme-toggle,
  .site-head .site-cta {
    transition-duration: 0.01ms;
  }
}

/* Design elevation: glass bar, live tier badge, dropdown entrance.
   All motion is transform/opacity only and collapses under reduced motion. */

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html.fp-js .site-head {
    background: color-mix(in oklab, var(--fp-bg, #0b1f17) 86%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(1.4);
    backdrop-filter: blur(12px) saturate(1.4);
  }
  html[data-theme="light"].fp-js .site-head {
    background: color-mix(in oklab, var(--fp-bg, #f4faf7) 86%, transparent);
  }
}

.site-head .site-brand svg {
  transition: transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-brand:hover svg {
  transform: rotate(-4deg) scale(1.06);
}

.site-head .tier-badge[hidden] { display: none; }
.site-head .tier-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: inherit;
  white-space: nowrap;
  border: 1px solid color-mix(in oklab, var(--fp-green, #0e8a5f) 45%, transparent);
  background: color-mix(in oklab, var(--fp-green, #0e8a5f) 14%, transparent);
}
.site-head .tier-dot {
  position: relative;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--fp-green-soft, #34d399);
}
.site-head .tier-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: fp-live 2.4s var(--fp-ease) infinite;
}
@keyframes fp-live {
  0% { transform: scale(1); opacity: 0.7; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}

html.fp-js .site-head .site-dropdown.open .site-drop-list {
  animation: fp-drop 160ms var(--fp-ease);
}
@keyframes fp-drop {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .site-head .tier-dot::after,
  html.fp-js .site-head .site-dropdown.open .site-drop-list {
    animation: none;
  }
  .site-head .site-brand svg {
    transition-duration: 0.01ms;
  }
}

/* Narrow screens: the bar sheds furniture in priority order (logo, hamburger,
   CTA, toggle, plan pill) instead of overflowing. Without this the right
   cluster keeps its full width and forces horizontal page scroll. */
@media (max-width: 560px) {
  .site-head .site-head-inner { gap: 12px; padding: 0 14px; }
  .site-head .site-brand b { display: none; }
  .site-head .site-cta { padding: 8px 12px; font-size: 13.5px; }
  .site-head .site-right { gap: 8px; min-width: 0; }
}
/* The 44px hit regions are 30px wider than what they replaced, and until
   this block paid for them the collapsed bar simply overflowed. Against
   v0.7.1 at a 320px viewport: brand 28 to 44, hamburger 38 to 44, theme
   toggle 36 to 44. The row ran to x=343.5 where v0.7.1 ended it at 313.5,
   and the document read 320/343 (23px of horizontal scroll) where v0.7.1
   read 320/320. That is a WCAG 1.4.10 reflow failure at the reference
   width, and it only appears with the plan pill shown, which is the state
   this release exists for: ocr-web ships the badge hidden and reveals it
   after sign-in, so it was signed-in phone users who got the scrollbar.

   The 30px comes back out of spacing and pill chrome, never out of a hit
   region. Each number continues a ladder the wider blocks already walk:
   inner gap 20/12/8, inner padding 16/14/10, .site-right gap 10/8/6.
   Collapsed, the row is brand + hamburger + cluster, so the inner gap is
   spent twice and only the LEFT inner padding moves the far edge that
   decides scrollWidth. Budget at 320px, pill shown: 10 + 44 + 8 + 44 + 8 +
   (9 + 6 + 44 + 6 + 134.5) = 313.5, back to where v0.7.1 had it, with
   every control still 44px. */
@media (max-width: 430px) {
  .site-head .site-head-inner { gap: 8px; padding: 0 10px; }
  .site-head .site-brand .app { display: none; }
  /* Only here is the brand small enough to need the floor: wordmark and app
     name are both gone and the 28px mark alone would be the target. Above
     this width the nowrap content is already wider than 44px, so declaring
     the floor there only broke the automatic minimum size. */
  .site-head .site-brand { min-width: 44px; justify-content: center; }
  .site-head .site-right { gap: 6px; }
  /* The pill is already only a dot here: .tier-label goes to display: none
     just below, so the border, background and 7px of side padding are a
     ring around a 7px dot and 14px of the row. Shed the ring, keep the
     indicator. The dot and its live pulse both survive, so a signed-in user
     still sees plan status, and the badge keeps its title attribute. The
     pill is last in the priority order at the head of this narrow-screen
     section, and the ring is chrome rather than content, which is why it
     goes before any 44px control is touched. */
  .site-head .tier-badge {
    padding: 0;
    gap: 0;
    border-color: transparent;
    background: none;
  }
  .site-head .tier-label { display: none; }
  .site-head .site-cta { padding: 7px 10px; font-size: 13px; }
}

/* Stacked rows get the floor only where the frame is actually thumbed. Above
   900px the dropdown keeps its denser pointer rhythm: rows are 33px tall
   and 230px+ wide, clearing WCAG 2.5.8 AA on size alone, no exception
   needed. */
@media (max-width: 900px) {
  .site-head .site-drop-list a,
  .site-head .site-drop-list span[aria-current] {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* FormsPal shared footer. Scope everything under .site-foot (plus html for
   theme variants). Dark-first; properties override the --fp-* variables.
   No JS: the footer is fully static. */

.site-foot {
  background: var(--fp-bg, #0b1f17);
  color: var(--fp-ink, #eaf5ef);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  /* Dimmed text uses mixed colors, never opacity. Opacity dims toward
     whatever is behind: that keeps contrast on a dark backdrop and destroys
     it on a light one, which is how the light theme fell under 4.5:1. */
  --fp-foot-soft: color-mix(in oklab, var(--fp-ink, #eaf5ef) 85%, var(--fp-bg, #0b1f17));
  --fp-foot-label: color-mix(in oklab, var(--fp-ink, #eaf5ef) 78%, var(--fp-bg, #0b1f17));
  --fp-foot-muted: color-mix(in oklab, var(--fp-ink, #eaf5ef) 70%, var(--fp-bg, #0b1f17));
  --fp-foot-link: color-mix(in oklab, var(--fp-green, #0e8a5f) 45%, #fff);
}
html[data-theme="light"] .site-foot {
  /* Fallbacks must flip with the theme too: a property that does not define
     --fp-ink/--fp-bg would otherwise dim light-theme text using the dark
     default ink and land at ~1.5:1. */
  --fp-foot-soft: color-mix(in oklab, var(--fp-ink, #10231a) 85%, var(--fp-bg, #f4faf7));
  --fp-foot-label: color-mix(in oklab, var(--fp-ink, #10231a) 78%, var(--fp-bg, #f4faf7));
  --fp-foot-muted: color-mix(in oklab, var(--fp-ink, #10231a) 70%, var(--fp-bg, #f4faf7));
  --fp-foot-link: color-mix(in oklab, var(--fp-green, #0e8a5f) 72%, #000);
}
html[data-theme="light"] .site-foot {
  background: var(--fp-bg, #f4faf7);
  color: var(--fp-ink, #10231a);
  border-top-color: rgba(0, 0, 0, 0.08);
}

/* Same reasoning as .site-head-inner in header.css: own the box model rather
   than inheriting whatever reset the host page happens to have. */
.site-foot .foot-cols,
.site-foot .foot-bottom-inner,
.site-foot .foot-ghost {
  box-sizing: border-box;
}

.site-foot .foot-cols {
  max-width: 1120px;
  margin: 0 auto;
  padding: 40px 16px 28px;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr;
  gap: 28px;
}

.site-foot .foot-brand svg { width: 34px; height: 34px; }
.site-foot .foot-brand b {
  display: inline-block;
  margin-left: 8px;
  font-size: 17px;
  vertical-align: super;
}
.site-foot .foot-brand p {
  font-size: 14px;
  line-height: 1.5;
  color: var(--fp-foot-soft);
  margin: 10px 0;
}
.site-foot .foot-brand a {
  color: var(--fp-foot-link);
  text-decoration: none;
  font-size: 14px;
}
.site-foot .foot-addr {
  font-style: normal;
  font-size: 13px;
  color: var(--fp-foot-label);
  margin-top: 12px;
  line-height: 1.5;
}
.site-foot .foot-addr strong { display: block; }

.site-foot .foot-col .foot-col-title {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fp-foot-label);
  margin: 4px 0 12px;
  font-weight: 600;
}
.site-foot .foot-col ul { list-style: none; margin: 0; padding: 0; }
.site-foot .foot-col li { margin: 0 0 9px; }
.site-foot .foot-col a {
  color: var(--fp-foot-soft);
  text-decoration: none;
  font-size: 14px;
}
.site-foot .foot-col a:hover { color: var(--fp-foot-link); }
.site-foot .foot-col span[aria-current] { font-size: 14px; color: var(--fp-foot-muted); }

.site-foot .foot-bottom { border-top: 1px solid rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-foot .foot-bottom { border-top-color: rgba(0, 0, 0, 0.08); }
.site-foot .foot-bottom-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 14px 16px 18px;
  font-size: 13px;
  color: var(--fp-foot-soft);
}
.site-foot .foot-disclaimer { margin: 0 0 10px; line-height: 1.55; }
.site-foot .foot-legal { display: block; }
.site-foot .foot-legal a {
  color: inherit;
  text-decoration: none;
  margin-right: 14px;
}
.site-foot .foot-legal a:hover { color: var(--fp-foot-link); }

/* The frame owns focus for its own components: a property that ships no
   global focus style (or resets outlines) must not lose the focus ring. */
.site-foot a:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: 4px;
}

@media (max-width: 900px) {
  .site-foot .foot-cols { grid-template-columns: 1fr 1fr; }
  .site-foot .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  .site-foot .foot-cols { grid-template-columns: 1fr; }
}

/* Match the header's gutter scale. The bar narrows to 14px then 10px so it can
   shed furniture instead of overflowing, but the footer stayed at a flat 16px,
   so footer content sat 2px then 6px inboard of the brand directly above it.
   Two gutters on one page is visible as a broken alignment line on any phone. */
@media (max-width: 560px) {
  .site-foot .foot-cols,
  .site-foot .foot-bottom-inner,
  .site-foot .foot-ghost { padding-inline: 14px; }
}
@media (max-width: 430px) {
  .site-foot .foot-cols,
  .site-foot .foot-bottom-inner,
  .site-foot .foot-ghost { padding-inline: 10px; }
}

/* Design elevation: signature top rule, heading accent ticks, link
   micro-shift, ghost wordmark half-cropped behind the bottom bar. */

.site-foot {
  border-top: 2px solid var(--fp-green, #0e8a5f);
}
.site-foot .foot-col .foot-col-title::before {
  content: "";
  display: block;
  width: 18px;
  height: 2px;
  margin-bottom: 8px;
  background: var(--fp-green, #0e8a5f);
}
.site-foot .foot-col a {
  display: inline-block;
  transition: color var(--fp-dur, 150ms) var(--fp-ease, ease-out), transform var(--fp-dur, 150ms) var(--fp-ease, ease-out);
}
.site-foot .foot-col a:hover {
  transform: translateX(2px);
}
.site-foot .foot-ghost {
  max-width: 1120px;
  margin: 8px auto -0.4em;
  padding: 0 16px;
  font-weight: 800;
  font-size: clamp(40px, 13vw, 190px);
  white-space: nowrap;
  line-height: 1;
  letter-spacing: -0.045em;
  opacity: 0.05;
  user-select: none;
  pointer-events: none;
  overflow-wrap: anywhere;
}
.site-foot .foot-bottom {
  position: relative;
  background: var(--fp-bg, #0b1f17);
}
html[data-theme="light"] .site-foot .foot-bottom {
  background: var(--fp-bg, #f4faf7);
}
@media (prefers-reduced-motion: reduce) {
  .site-foot .foot-col a { transition-duration: 0.01ms; }
}

/* Footer rows are 14px type on a 9px rhythm: a 16.5px box at 25.5px pitch.
   That clears WCAG 2.5.8 AA on the spacing exception but sits well under the
   44px Apple asks for. Raised only where the footer is thumbed; above 900px
   the columns keep their denser desktop rhythm. */
/* A second @media (max-width: 900px) block on purpose: keep it separate
   from the one above. The "design elevation" section earlier in this file
   sets .site-foot .foot-col a { display: inline-block } at equal
   specificity. Merging these rules up there would put them before that one
   in source order, so inline-block would win the cascade and silently
   shrink the 44px row back down to a text-width link. */
@media (max-width: 900px) {
  .site-foot .foot-col li { margin: 0; }
  .site-foot .foot-col a,
  .site-foot .foot-col span[aria-current] {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  /* Width needs the floor too: these are short words, and a hit region is
     44x44, not 44 tall. Measured at 880px before this rule: Privacy 44.19,
     Cookies 48.64, Terms 37.21, CCPA 34.76, DMCA 38.32. They are inline-flex
     boxes on a line box, so widening them pushes their neighbours along the
     row instead of changing any layout around it. */
  .site-foot .foot-legal a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    margin-right: 18px;
  }
}
/* fp-shared-frame:end */

/* Hub browse mega-dropdown (property-owned): one shared-frame dropdown at
   every width. Six category groups sit in a 3-across grid with compact rows;
   the panel spans the bar and scrolls past 70vh. All 110 dofollow links stay
   server-rendered. */
.site-head .site-nav { overflow: visible; }
.site-head .site-dropdown.site-dropdown-mega { position: static; }
html.fp-js .site-head .site-dropdown-mega .site-drop-list {
  left: 16px;
  right: 16px;
  max-width: 1088px;
  margin: 0 auto;
  max-height: min(74vh, 680px);
  overflow: auto;
  padding: 20px 24px;
  display: none;
}
html.fp-js .site-head .site-dropdown-mega.open .site-drop-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px 28px;
  align-items: start;
}
.site-head .site-mega .mega-group { min-width: 0; }
/* Rehomed from widget/page.css, where it was the one live declaration left in
   an orphaned block (see the note there). Kept as a guard for the day
   .mega-cols stops being display: block: measured today the columns are
   block-level boxes, so min-width: auto already resolves to 0 and this changes
   no geometry, but as a flex or grid item it would be the difference between
   0 and min-content. */
.site-head .site-mega .mega-col { min-width: 0; }
.site-head .site-mega .mega-cat {
  margin: 0 0 6px;
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fp-green, #0e8a5f);
}
.site-head .site-mega .mega-cols { display: block; }
.site-head .site-mega .mega-cols ul { list-style: none; margin: 0; padding: 0; }
.site-head .site-drop-list.site-mega a {
  padding: 3px 8px;
  font-size: 13.5px;
}
.site-head .site-mega .mega-head {
  display: block;
  font-size: 11.5px;
  font-weight: 700;
  opacity: 0.55;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 8px 0 2px;
}
.site-head .site-mega .mega-group > .mega-cols > .mega-head:first-child,
.site-head .site-mega .mega-cols > .mega-col:first-child > .mega-head { margin-top: 0; }
.site-head .site-mega .mega-sub { padding-left: 12px; }
.site-head .site-drop-list.site-mega .mega-sub a { font-size: 12.5px; opacity: 0.8; }
/* Stays a media query on purpose. This one asks how many columns fit across
   the panel, and the panel spans the bar, so its width is a function of the
   viewport and nothing else. It is not asking whether the nav fits. */
@media (max-width: 900px) {
  html.fp-js .site-head .site-dropdown-mega.open .site-drop-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Collapsed-state compensation. Keyed to the frame's collapsed class, not to
   a width, because since shared-frame v0.9.0 header.js collapses the bar on a
   live fit measurement rather than at a breakpoint. The bar is now collapsed
   from wherever the nav stops fitting on down (measured on the hub at 758px),
   which is a wider band than the 719px this block used to name.

   While it was still @media (max-width: 719px) the compensation did not apply
   inside that gap: the desktop rule above kept the panel at display: none, and
   the frame's pointer-events: none on .site-drop-btn meant it could not be
   opened either, so all 110 browse links were unreachable across the band.

   Specificity, verified rather than assumed. These selectors are (0,5,1) and
   (0,6,1). They beat the property's own desktop rules above at (0,4,1) and
   (0,5,1) outright. Against the frame's collapsed rules they beat the (0,4,1)
   base outright and tie the (0,6,1) open rule, which resolves here on source
   order because the property block follows the vendored block. That tie is
   inert in both directions: the frame's rule also sets display: block, and it
   sets none of the other properties this block sets. */
html.fp-js.fp-nav-collapsed .site-head .site-dropdown-mega .site-drop-list,
html.fp-js.fp-nav-collapsed .site-head .site-dropdown-mega.open .site-drop-list {
  left: auto; right: auto; margin: 0; max-height: none; overflow: visible;
  padding: 6px; display: block;
}

