/* Bindingstone base stylesheet: mechanics only, zero brand opinions.
 *
 * Served from the assembly at:
 *   /_content/Bindingstone.WebKit/css/base.css
 *
 * Load this BEFORE the site's own stylesheet:
 *   <link rel="stylesheet" href="/_content/Bindingstone.WebKit/css/base.css" />
 *   <link rel="stylesheet" href="/site.css" />
 *
 * What belongs here: reset, layout primitives, and the structural/behavioral
 * rules that make shared JS work (mobile drawer states, scroll reveal, focus
 * visibility). What does NOT belong here: colors, fonts, spacing scale, or any
 * decision that makes a site look like a particular brand. Those live in the
 * site's own stylesheet.
 *
 * Everything below reads from CSS custom properties with fallbacks, so this file
 * adapts to whatever tokens the site defines and still renders sanely when it
 * defines none.
 */

/* ---------------------------------------------------------------- reset ---- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body, system-ui, -apple-system, "Segoe UI", sans-serif);
  color: var(--ink, #1c1c1e);
  background: var(--paper, #ffffff);
  line-height: 1.55;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }

h1, h2, h3, h4 {
  font-family: var(--font-display, inherit);
  line-height: 1.15;
  letter-spacing: -0.01em;
}

/* Never remove focus outlines outright. Show them for keyboard users only, so
   the site stays navigable without a mouse. */
:focus-visible {
  outline: 2px solid var(--action, #1c1c1e);
  outline-offset: 2px;
}

/* ------------------------------------------------------------- primitives -- */

.wrap {
  width: min(100% - 2 * var(--gutter, 20px), var(--wrap, 1180px));
  margin-inline: auto;
}

.section { padding-block: var(--section-pad, clamp(48px, 7vw, 96px)); }
.section--tight { padding-block: var(--section-pad-tight, clamp(32px, 4vw, 56px)); }

/* Wide content must scroll inside its own container rather than making the
   whole page scroll sideways on a phone. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Keyboard users need a way past the nav. Hidden until focused. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 999;
  padding: 12px 20px;
  background: var(--ink, #1c1c1e);
  color: var(--paper, #fff);
  text-decoration: none;
}
.skip-link:focus { left: 8px; top: 8px; }

/* ------------------------------------------------- mobile nav drawer ------- */
/* Structural states for the shared mobilenav.js, which ships no styling of its
 * own: without these rules the hamburger appears to do nothing.
 *
 * THE OPEN CLASS GOES ON <body>, NOT ON .mnav. The script does
 * document.body.classList.add('mnav-open'), so selectors must be written as
 * `body.mnav-open .mnav`. Writing `.mnav.mnav-open` looks right, matches
 * nothing, and produces a drawer that silently never opens.
 *
 * Colors and type come from the site's tokens. Only geometry and the open/closed
 * transition live here. */

.mnav {
  position: fixed;
  inset: 0;
  z-index: 200;
  visibility: hidden;
  pointer-events: none;
}

body.mnav-open .mnav {
  visibility: visible;
  pointer-events: auto;
}

.mnav__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  opacity: 0;
  transition: opacity 0.22s ease;
}
body.mnav-open .mnav__backdrop { opacity: 1; }

.mnav__panel {
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  width: min(88vw, 360px);
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* padding-top is overwritten inline by the script, which measures the real
     header height so the first link clears it on any site. This is the fallback
     for the moment before that runs. */
  padding: 72px 24px 24px;
  overflow-y: auto;
  background: var(--paper, #ffffff);
  box-shadow: -12px 0 40px rgba(0, 0, 0, 0.18);
  transform: translateX(100%);
  transition: transform 0.24s ease;
}
body.mnav-open .mnav__panel { transform: translateX(0); }

.mnav__link,
.mnav__cta {
  display: block;
  padding: 14px 4px;
  color: inherit;
  text-decoration: none;
  font-weight: 600;
  border-bottom: 1px solid var(--bord-soft, var(--bord, rgba(0, 0, 0, 0.08)));
}
.mnav__cta {
  margin-top: 16px;
  border-bottom: 0;
  text-align: center;
  border-radius: var(--radius, 8px);
  background: var(--action, #1c1c1e);
  color: var(--paper, #fff);
}

/* Stops the page behind the drawer from scrolling while it is open.
 *
 * position: fixed rather than overflow: hidden, because the script pairs this
 * with an inline `body.style.top = -scrollY` and restores the scroll position on
 * close. That is the iOS-safe pattern, and the offset does nothing unless the
 * body is taken out of flow. width: 100% keeps the fixed body full-bleed. */
body.mnav-locked {
  position: fixed;
  width: 100%;
  overflow: hidden;
}

/* The toggle itself is hidden on desktop; the site decides at which width its
   own nav collapses by overriding this breakpoint. */
.mnav-toggle { display: none; background: none; border: 0; cursor: pointer; padding: 8px; }

@media (max-width: 860px) {
  .mnav-toggle { display: inline-flex; }
}
@media (min-width: 861px) {
  /* Never leave the drawer visible on desktop, even if a stale open class
     survives a resize. */
  .mnav { display: none; }
}

/* ------------------------------------------------------- scroll reveal ----- */
/* Opt-in: add data-reveal to an element.
 *
 * The hidden start state is scoped to .js-reveal, which reveal.js sets on <html>
 * before first paint. That scoping is the whole point: writing
 * `[data-reveal] { opacity: 0 }` unscoped would leave the content permanently
 * invisible for anyone whose JS failed to load, which is a content-disappears
 * bug wearing an animation costume. With no JS, nothing here applies and the
 * page renders fully visible. */

.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
.js-reveal [data-reveal].is-revealed { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------- NAP block --- */

/* NapBlock.razor emits the name, the service area or address, the phone and the
   email as sibling elements inside <address>. Nothing styled any of them: not
   this file, not registers.css, and not one of the five client stylesheets. So
   every site rendered its footer address as a single run-on string,
   "Black Widow SealcoatingServing Eau Claire, WI, Menomonie, WI..." with the
   phone number welded to the end of it, in the browser's default italic.
   
   That is a structural failure rather than a brand decision, which is why the
   fix is here. Grid puts each part on its own row without the component having
   to emit <br>, so a site that wants the block on one line (a header, a
   contact card) overrides one property instead of fighting markup.

   font-style is reset because <address> is italic by default in every browser
   and no site asked for that. */

.nap {
  font-style: normal;
  display: grid;
  gap: var(--nap-gap, 0.3rem);
  justify-items: start;
}

/* The street, city, region and postal parts belong on one line inside their
   own row, so this one stays inline. */
.nap-addr { display: block; }

/* --------------------------------------------------------------- print ----- */

@media print {
  .mnav, .mnav-toggle, .skip-link { display: none !important; }
  body { color: #000; background: #fff; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
}
