/* ---------------------------------------------------------------------------
   605 Diecast — behavioural CSS.

   This file is the same on every reboot. It holds the mechanics that took real
   debugging to get right: the sticky header, the CSS-only burger, the mobile
   nav panel, the quick-action bar, back-to-top, tap targets and WordPress's
   layout quirks. There is no colour, no typeface and no personality in here —
   all of that belongs in style.css, which is written fresh for each site.

   Import it first, then let style.css paint on top:
       @import url("assets/mechanics.css");

   ── The contract ──────────────────────────────────────────────────────────
   style.css MUST define these on :root, or the mechanics fall back to
   something plain but functional:

     --dc-focus      focus ring colour
     --dc-nav-bg     mobile nav panel background (must be opaque)
     --dc-burger     colour of the three burger bars
     --dc-header-h   starting guess at header height; JS overwrites it

   and MUST use these class names, because the rules below target them:

     .dc-header   .dc-headbar   .dc-brand   .dc-burger
     .dc-nav      .dc-nav__inner .dc-nav__link .dc-nav__foot
     .dc-band     full-bleed section wrapper
     .dc-footer   .dc-actionbar .dc-ab .dc-top

   The mobile breakpoint is 52rem and is hard-coded here and in site.js
   (52.0625rem for the matchMedia). Change one, change both.
   ------------------------------------------------------------------------- */

/* WordPress sets box-sizing:border-box on its own blocks and on form controls,
   but NOT globally — so a plain <a> or <button> inherits content-box from the
   document. min-height then means "content box at least this tall" and padding
   and border are added on top: a 52px min-height button with 27px of padding
   and 4px of border renders 83px tall. Set it once, here, before anything
   else assumes it. */
*,*::before,*::after{box-sizing:border-box}

:root{
  /* JS measures the real values; these are the no-JS fallbacks. */
  --dc-header-h:76px;
  --dc-stick-h:76px;
}

html{scroll-behavior:smooth;scroll-padding-top:calc(var(--dc-stick-h, var(--dc-header-h)) + 1.25rem)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}

/* Top-level blocks carry their own padding, so WordPress's automatic block gap
   between them just opens a stripe of body colour under the header. */
.wp-site-blocks > *{margin-block-start:0;margin-block-end:0}

:focus-visible{outline:3px solid var(--dc-focus,#000);outline-offset:3px;border-radius:2px}
p{text-wrap:pretty}
h1,h2,h3{text-wrap:balance}
img{max-width:100%;height:auto}

.dc-visually-hidden{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ------------------------------------------------------------- header ---- */
/* Sticky has to go on the WRAPPER. WordPress renders the template part inside
   <header class="wp-block-template-part">, which is exactly as tall as the bar,
   so position:sticky on the bar itself has no room to stick in and the header
   simply scrolls away. */
header.wp-block-template-part{position:sticky;top:0;z-index:100}
.dc-headbar{display:flex;align-items:center;gap:1.35rem}
.dc-brand{display:flex;align-items:center;margin-right:auto;min-height:44px;text-decoration:none}
.dc-nav__link{white-space:nowrap}
.dc-nav__foot{display:none}
.dc-burger{display:none}

/* --------------------------------------------------------- mobile menu --- */
/* The checkbox sits inside the button at opacity 0 rather than clipped
   off-screen. A clipped input receives focus on tap and the browser scrolls the
   page to reach it, which reads as the menu "reloading the page". */
.dc-burger{position:relative;flex:0 0 auto;width:44px;height:44px;align-items:center;justify-content:center;cursor:pointer}
.dc-burger__box{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;opacity:0;cursor:pointer;-webkit-appearance:none;appearance:none}
.dc-burger__box:focus-visible + .dc-burger__bars{outline:2px solid var(--dc-focus,#000);outline-offset:8px;border-radius:2px}
.dc-burger__bars{position:relative;display:block;width:25px;height:17px;pointer-events:none}
.dc-burger__bars i{
  position:absolute;left:0;right:0;height:2.5px;
  background:var(--dc-burger,currentColor);border-radius:2px;
  transition:top .2s ease, transform .2s ease, opacity .12s linear;
}
.dc-burger__bars i:nth-child(1){top:0}
.dc-burger__bars i:nth-child(2){top:7.25px}
.dc-burger__bars i:nth-child(3){top:14.5px}
.dc-burger__box:checked + .dc-burger__bars i:nth-child(1){top:7.25px;transform:rotate(45deg)}
.dc-burger__box:checked + .dc-burger__bars i:nth-child(2){opacity:0}
.dc-burger__box:checked + .dc-burger__bars i:nth-child(3){top:7.25px;transform:rotate(-45deg)}
@media (prefers-reduced-motion:reduce){.dc-burger__bars i,.dc-nav{transition:none!important}}

@media (max-width:52rem){
  .dc-burger{display:inline-flex}

  /* The sticky header is its own stacking context, so the panel's z-index 90
     is measured against its siblings INSIDE the header — which would paint the
     panel over the burger and swallow the tap that should close it. */
  .dc-brand,.dc-burger{position:relative;z-index:95}

  .dc-nav{
    position:fixed;inset:0;z-index:90;
    background:var(--dc-nav-bg,#fff);
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
    visibility:hidden;opacity:0;transition:opacity .2s ease,visibility .2s ease;
  }
  .dc-header:has(.dc-burger__box:checked) .dc-nav,
  .dc-header[data-nav="open"] .dc-nav{visibility:visible;opacity:1}

  body:has(.dc-burger__box:checked),body[data-nav="open"]{overflow:hidden}

  /* The action bar (z 95) and back-to-top (z 96) both outrank the panel, so
     they would punch through it. The panel carries its own actions. */
  body:has(.dc-burger__box:checked) .dc-actionbar,
  body:has(.dc-burger__box:checked) .dc-top,
  body[data-nav="open"] .dc-actionbar,
  body[data-nav="open"] .dc-top{display:none!important}

  .dc-nav__inner{
    display:block;max-width:34rem;margin:0 auto;
    /* The panel is position:fixed, so it starts at the TOP OF THE VIEWPORT —
       but the header does not always sit there. Anything above it in the
       document (a preview strip, an announcement bar) pushes it down while the
       page is scrolled to the top, and offsetting by the header's own height
       then slides the first link underneath the logo. JS measures the header's
       bottom edge each time the panel opens and publishes it as --dc-nav-top;
       the header height is the fallback for no-JS. */
    padding:calc(var(--dc-nav-top, var(--dc-header-h)) + .75rem) 1.25rem 2.5rem;
    min-height:100%;
  }
  .dc-nav__link{display:flex;align-items:center;min-height:58px}
  .dc-nav__foot{display:block;padding-top:1.75rem}
}

/* Short screens in landscape: shrink the rows so the CTA stays reachable. */
@media (max-width:52rem) and (max-height:34rem){
  .dc-nav__link{min-height:46px}
  .dc-nav__foot{padding-top:1rem}
}

/* ------------------------------------------ mobile quick action bar ------ */
/* On mobile the header CTA collapses into the hamburger, which buries the two
   things a visitor actually wants. This keeps both a thumb-tap away without
   parking a permanent slab across the page. Colours belong to style.css. */
.dc-actionbar{display:none}
@media (max-width:52rem){
  .dc-actionbar{
    display:block;position:fixed;left:0;right:0;bottom:0;z-index:95;
    padding:0 .75rem calc(.75rem + env(safe-area-inset-bottom,0px));
    /* The wrapper spans the viewport so the pills can centre on a tablet, but
       only the pills themselves should ever swallow a tap. */
    pointer-events:none;
    transform:translateY(calc(100% + 1rem));opacity:0;visibility:hidden;
    transition:transform .26s cubic-bezier(.22,.61,.36,1),opacity .2s ease,visibility .26s;
  }
  .dc-actionbar[data-show="true"]{transform:none;opacity:1;visibility:visible}
  .dc-actionbar__inner{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;max-width:26rem;margin:0 auto;pointer-events:auto}
  .dc-ab{display:flex;align-items:center;justify-content:center;gap:.5rem;min-height:52px;text-decoration:none}
}
@media (max-width:52rem) and (prefers-reduced-motion:reduce){.dc-actionbar{transition:none}}

/* --------------------------------------------------------- back to top --- */
.dc-top{
  position:fixed;right:1rem;z-index:96;
  bottom:calc(1rem + env(safe-area-inset-bottom,0px));
  width:46px;height:46px;cursor:pointer;display:grid;place-items:center;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .2s ease,visibility .2s,transform .2s ease,bottom .22s ease;
}
.dc-top[data-show="true"]{opacity:1;visibility:visible;transform:none}
/* Step up over the action bar by its MEASURED height, not by the 52px
   min-height of a pill — those differ the moment a label wraps or the reader
   turns their text size up, and the bar carries its own padding and safe-area
   inset on top. */
body[data-ab="shown"] .dc-top{bottom:calc(1rem + var(--dc-ab-h,64px) + env(safe-area-inset-bottom,0px))}
@media (prefers-reduced-motion:reduce){.dc-top{transition:none}}

/* ----------------------------------------------------- mobile tap targets */
/* Measured at a real 390px viewport: footer and inline links run 18-34px tall.
   44px is the floor a thumb needs. Vertical padding on an inline box grows the
   hit area without changing the line box, so paragraph spacing is unaffected. */
.dc-footer ul a{display:inline-flex;align-items:center;min-height:44px}
.dc-crumbs a{display:inline-flex;align-items:center;min-height:44px}
@media (max-width:52rem){
  .dc-prose p > a,.dc-prose li > a{padding-block:.5rem}
}

/* --------------------------------------------------- alignment repairs --- */
/* WordPress's constrained layout centres any child narrower than the content
   width. Body text capped at ~68ch is narrower, so every paragraph gets centred
   and appears indented next to a full-width heading. Pin them left instead.
   Specificity here has to beat `:root :where(...)`. */
.dc-band > *{
  margin-left:max(0px, calc((100% - var(--wp--style--global--content-size)) / 2)) !important;
  margin-right:auto !important;
}

/* NEVER height:100% on a grid item. A grid item already stretches to its row,
   so it adds nothing — and it resolves against the grid AREA, pinning the item
   at the row height computed before the webfont loaded. The content then needs
   more room, overflows the item's own box, and paints over whatever follows
   the grid. Let the row size to content. */

@media print{
  .dc-header,.dc-footer,.dc-actionbar,.dc-top{display:none!important}
  .dc-band{background:#fff!important;color:#000!important;padding-block:1rem}
}
