/* ==========================================================================
   MZELC childcare PmWiki skin - v1
   --------------------------------------------------------------------------
   Architecture ported from stk-2026-v13 (St. Thomas Kinsmen), which came from
   the District 1 Kin skin. Template zones, the layout shell, the off-canvas
   mobile menu, and the print/reduced-motion handling all follow that lineage.

   NAMESPACE: every class and custom property here uses "mz-". This skin does
   NOT share wiki markup with district1kin.ca or stthomaskinsmen.com, so the
   d1- prefix bought nothing. d1-skin-helpers-v19.md does not apply -- use
   mz-skin-helpers-v1.md instead.

   Design: soft rounded shapes on a warm off-white canvas, a purple welcome
   band with decorative circles, a left menu whose items carry large rainbow
   bullets, and a single content-block pattern (.mz-note / .mz-room) that
   takes any of six rainbow colour modifiers.

   Sections:
     01 Tokens            05 Hero                09 Footer / bottom
     02 Base elements     06 Left nav + aside    10 Responsive
     03 Layout shells     07 Content column      11 Print + motion
     04 Keyline + header  08 Content blocks
   ========================================================================== */

/* 01 - Tokens ------------------------------------------------------------ */
:root {
  /* --- The rainbow. Six hues, each with a soft tint for block backgrounds
         and a dark ink that meets AA contrast on that tint. --- */
  --mz-red: #E24B4A;
  --mz-red-soft: #FCEBEB;
  --mz-red-ink: #A32D2D;
  --mz-red-deep: #501313;

  --mz-orange: #EF9F27;
  --mz-orange-soft: #FAEEDA;
  --mz-orange-ink: #854F0B;
  --mz-orange-deep: #412402;

  --mz-yellow: #FAC775;
  --mz-yellow-soft: #FDF3E2;
  --mz-yellow-ink: #8A6314;
  --mz-yellow-deep: #4A340A;

  --mz-green: #639922;
  --mz-green-soft: #EAF3DE;
  --mz-green-ink: #3B6D11;
  --mz-green-deep: #173404;

  --mz-blue: #378ADD;
  --mz-blue-soft: #E6F1FB;
  --mz-blue-ink: #185FA5;
  --mz-blue-deep: #042C53;

  --mz-purple: #7F77DD;
  --mz-purple-soft: #EEEDFE;
  --mz-purple-ink: #534AB7;
  --mz-purple-deep: #26215C;

  /* Teal is a seventh, off-rainbow hue reserved for pinned notices so they
     never collide with a section colour. */
  --mz-teal: #1D9E75;
  --mz-teal-soft: #E3F4EC;
  --mz-teal-ink: #0E6B4C;
  --mz-teal-deep: #083B2A;

  /* Primary action colour: the deep purple. Buttons, links, focus. */
  --mz-accent: var(--mz-purple-ink);
  --mz-accent-hover: #3F37A0;

  /* --- Neutrals --- */
  --mz-ink: #2C2C2A;
  --mz-body: #444441;
  --mz-muted: #5F5E5A;
  /* WCAG 2.0 AA. The previous #888780 measured 3.61:1 on white and 3.13:1 on
     the canvas, below the 4.5:1 needed for normal text -- and this token is
     used almost entirely at small sizes (kickers, breadcrumb, menu and aside
     labels, footer headings, credit strip, the day-rhythm times, the header
     tagline). #66655F measures 5.85:1 on white and 5.08:1 on canvas. */
  --mz-faint: #66655F;
  --mz-line: #D3D1C7;
  /* Focus ring. The old orange #EF9F27 was only 2.17:1 against white, so the
     indicator itself was hard to see -- which undermines 2.4.7 in practice
     even though WCAG 2.0 sets no contrast minimum for non-text. #B5730F is
     3.87:1 on white and 3.37:1 on canvas, clearing the 2.1 SC 1.4.11 bar too. */
  --mz-focus: #B5730F;
  --mz-canvas: #F1EFE8;        /* warm off-white page background */
  --mz-card: #ffffff;

  /* --- Metrics --- */
  --mz-max: 1200px;
  --mz-gutter: clamp(1rem, 2.6vw, 1.9rem);
  --mz-col-gap: clamp(.9rem, 1.8vw, 1.35rem);
  --mz-nav-col-min: 235px;
  --mz-nav-col-max: 275px;
  --mz-copy-inset: clamp(1.1rem, 2.4vw, 1.9rem);  /* padding inside white boxes */
  --mz-item-pad: 1.05rem;      /* shared text inset for menu rows and breadcrumb */
  --mz-navcard-pad: clamp(.9rem, 1.8vw, 1.15rem);

  /* THE RAIL. One shared vertical alignment line. The left menu's card is
     inset by --mz-navcard-pad and its rows by --mz-item-pad, so menu text
     starts this far in from the card edge. The logo, the breadcrumb, and the
     footer grid all indent by the same amount so their left edges line up
     with the menu content in a single clean column. Change one value here and
     all four move together. */
  --mz-rail: calc(var(--mz-navcard-pad) + var(--mz-item-pad));

  --mz-logo-w: clamp(210px, 27vw, 320px);
  --mz-logo-h: clamp(66px, 8.5vw, 108px);
  /* Positive values let a tall logo hang below the header band. The band has
     overflow:visible, so nothing clips. 0 keeps it fully inside. */
  --mz-logo-drop: 0px;
  --mz-footer-logo-w: clamp(150px, 18vw, 210px);

  /* Optical correction for the header logo. Most logo artwork carries a few
     pixels of transparent margin inside the file, which makes a
     mathematically-aligned logo look inset next to live text. This pulls it
     back. Set to 0 if your logo is cropped tight to the artwork. */
  --mz-logo-nudge: -7px;

  /* Space above AND below the breadcrumb. One token drives both, so the
     breadcrumb stays optically centred between the header and the content
     boxes. See section 05. */
  --mz-title-gap: clamp(.9rem, 1.9vw, 1.35rem);

  /* Shared motion. Every transition in the skin uses these two values so
     hovers feel identical whether the control is in the header, the menu, or
     the page body. Reduced-motion is handled in section 11. */
  --mz-ease: cubic-bezier(.2, .7, .3, 1);
  --mz-t: .2s;
  --mz-lift: translateY(-1px);

  /* Heading accent: h2 and h4 take this, h1/h3/h5 stay near-black. */
  --mz-heading-alt: var(--mz-purple-ink);

  /* --- Shape. This skin is deliberately round; STK is deliberately square. */
  --mz-radius: 14px;           /* content blocks */
  --mz-radius-lg: 18px;        /* call-to-action blocks */
  --mz-radius-pill: 999px;     /* buttons, tags, active menu row */
  --mz-bar: .5rem;             /* left colour bar on .mz-note / .mz-room */
  --mz-keyline: 6px;

  --mz-shadow-float: 0 2px 10px rgba(44, 44, 42, .07);
  --mz-shadow-lift: 0 6px 20px rgba(44, 44, 42, .11);

  /* Fonts are config-driven from the php; these are the built-in defaults. */
  --mz-font: "Nunito Sans", system-ui, -apple-system, "Segoe UI", Roboto, Arial, Helvetica, sans-serif;
  --mz-display: "Nunito", "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
}

/* Colour modifier classes. Add ONE of these alongside .mz-note, .mz-room,
   .mz-feature, or .mz-step to recolour it. They only set variables, so the
   same six modifiers drive every block type. */
.mz-red    { --mz-c: var(--mz-red);    --mz-c-soft: var(--mz-red-soft);    --mz-c-ink: var(--mz-red-ink);    --mz-c-deep: var(--mz-red-deep); }
.mz-orange { --mz-c: var(--mz-orange); --mz-c-soft: var(--mz-orange-soft); --mz-c-ink: var(--mz-orange-ink); --mz-c-deep: var(--mz-orange-deep); }
.mz-yellow { --mz-c: var(--mz-yellow); --mz-c-soft: var(--mz-yellow-soft); --mz-c-ink: var(--mz-yellow-ink); --mz-c-deep: var(--mz-yellow-deep); }
.mz-green  { --mz-c: var(--mz-green);  --mz-c-soft: var(--mz-green-soft);  --mz-c-ink: var(--mz-green-ink);  --mz-c-deep: var(--mz-green-deep); }
.mz-blue   { --mz-c: var(--mz-blue);   --mz-c-soft: var(--mz-blue-soft);   --mz-c-ink: var(--mz-blue-ink);   --mz-c-deep: var(--mz-blue-deep); }
.mz-purple { --mz-c: var(--mz-purple); --mz-c-soft: var(--mz-purple-soft); --mz-c-ink: var(--mz-purple-ink); --mz-c-deep: var(--mz-purple-deep); }
.mz-teal   { --mz-c: var(--mz-teal);   --mz-c-soft: var(--mz-teal-soft);   --mz-c-ink: var(--mz-teal-ink);   --mz-c-deep: var(--mz-teal-deep); }


/* 02 - Base elements ------------------------------------------------------ */
* { box-sizing: border-box; }
html { font-size: 100%; scroll-behavior: smooth; }
html, body { overflow-x: hidden; }
body {
  min-height: 100vh;
  margin: 0;
  color: var(--mz-body);
  background: var(--mz-canvas);
  font-family: var(--mz-font);
  line-height: 1.65;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--mz-accent);
  text-decoration-color: rgba(83, 74, 183, .4);
  text-underline-offset: .18em;
  transition: color var(--mz-t) var(--mz-ease),
              text-decoration-color var(--mz-t) var(--mz-ease);
}
a:visited { color: #4C3F84; }
a:hover { color: var(--mz-accent-hover); text-decoration-color: currentColor; }

/* Underline sweep, shared by the header nav, the footer, and the credit
   strip so every link outside the page body animates identically.

   Drawn with an ::after bar rather than a background gradient. A gradient on
   the link itself makes axe-core give up on contrast entirely -- it reports
   "background color could not be determined due to a background gradient" for
   every such link, so a clean scan becomes impossible and an auditor has to
   check each one by hand. A transform-scaled pseudo bar animates identically
   and leaves the link's background transparent, which axe can resolve.

   Scoped to the REGION, not to specific block classes, so anything an editor
   drops into the footer picks it up. Buttons opt out in section 04. */
.header-nav a,
.site-footer a,
.template-bottom a {
  position: relative;
  color: var(--mz-muted);
  font-size: .88rem;
  text-decoration: none;
  transition: color var(--mz-t) var(--mz-ease);
}
.header-nav a::after,
.site-footer a::after,
.template-bottom a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--mz-t) var(--mz-ease);
}
.header-nav a:hover::after,
.site-footer a:hover::after,
.template-bottom a:hover::after { transform: scaleX(1); }
.header-nav a:hover,
.site-footer a:hover,
.template-bottom a:hover { color: var(--mz-accent); }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
label:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--mz-focus);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Visually hidden but still announced and still focusable. Used for the
   menu-close label's text, the search field's label, and anywhere else a
   control needs a name that the design doesn't show. Uses the clip technique
   rather than display:none or opacity:0 -- the first removes it from the
   accessibility tree, the second leaves a focusable element with no visible
   focus ring. */
.mz-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

img { max-width: 100%; height: auto; }
iframe { max-width: 100%; }
/* Horizontal rules -- the ---- markup in wikitext.

   Default: a hairline that fades out at both ends. A hard edge-to-edge line
   fights the rounded corners and soft shapes used everywhere else; a fading
   rule reads as a pause rather than a wall. Uses background rather than
   border so the gradient is possible. */
hr {
  height: 1px;
  border: 0;
  margin: clamp(1.4rem, 3vw, 2.1rem) 0;
  background: linear-gradient(90deg,
      transparent 0,
      var(--mz-line) 10%,
      var(--mz-line) 90%,
      transparent 100%);
}

/* Inside a coloured block, a rule picks up the block's own hue. */
:is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) hr {
  background: linear-gradient(90deg,
      transparent 0,
      var(--mz-c) 10%,
      var(--mz-c) 90%,
      transparent 100%);
  opacity: .6;
}

/* Rainbow variant, for a heavier section break. Wrap the ---- in a div:
     (:div class="mz-rule-rainbow":)
     ----
     (:divend:)                                                          */
.mz-rule-rainbow hr {
  height: 5px;
  border-radius: 3px;
  opacity: 1;
  background: linear-gradient(90deg,
    var(--mz-red)    0     16.66%,
    var(--mz-orange) 16.66% 33.33%,
    var(--mz-yellow) 33.33% 50%,
    var(--mz-green)  50%   66.66%,
    var(--mz-blue)   66.66% 83.33%,
    var(--mz-purple) 83.33% 100%);
}
/* Short variant of the same, matching the bar under an h1. */
.mz-rule-rainbow.mz-short hr { width: 92px; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--mz-display);
  line-height: 1.22;
  color: var(--mz-ink);
  font-weight: 700;
}

/* Skip link: visible only on keyboard focus. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: .6rem 1rem;
  background: var(--mz-accent);
  color: #fff;
  border-radius: 0 0 var(--mz-radius) 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; color: #fff; }


/* 03 - Layout shells ------------------------------------------------------ */
/* Bands run the full screen width; .template-inner constrains their content. */
.template-band { width: 100%; }
.template-inner {
  width: 100%;
  max-width: var(--mz-max);
  margin-inline: auto;
  padding-inline: var(--mz-gutter);
}

#TemplateWrapper {
  padding-block: var(--mz-title-gap) clamp(1.4rem, 2.8vw, 2.2rem);
}
@media (min-width: 901px) {
  #TemplateWrapper {
    display: grid;
    grid-template-columns: minmax(var(--mz-nav-col-min), var(--mz-nav-col-max)) minmax(0, 1fr);
    /* The last row MUST be 1fr. The main column spans all four rows, so
       without a flexible final row its height is distributed across every
       row and the aside gets pushed hundreds of pixels below the menu. */
    grid-template-rows: auto auto auto 1fr;
    grid-template-areas:
      "nav main"
      "sectionhero main"
      "aside main"
      ". main";
    /* Row-gap must stay 0: grid gaps apply around EMPTY tracks too, so a
       hidden aside would add a phantom row and the stretched main column
       would inherit it as dead white space. Vertical rhythm comes from
       margin-top on the boxes instead -- display:none boxes contribute none. */
    column-gap: var(--mz-col-gap);
    row-gap: 0;
    align-items: start;
  }
  #TemplateMainColumn { grid-area: main; min-width: 0; align-self: stretch; }
  .mz-nav-region { grid-area: nav; min-width: 0; }
  #TemplateSectionHero { grid-area: sectionhero; min-width: 0; margin-top: var(--mz-col-gap); }
  #TemplateAside { grid-area: aside; min-width: 0; margin-top: var(--mz-col-gap); }
  #TemplateNavToggle,
  #TemplateNavToggleLabel { display: none; }
}

/* The floating white boxes. */
.content-card,
.side-card {
  background: var(--mz-card);
  border-radius: var(--mz-radius);
  box-shadow: var(--mz-shadow-float);
  overflow: hidden;
}

/* Empty zones must not leave gaps.

   The hero cannot use :empty -- it ALWAYS contains the decorative circle
   span, so :empty never matches and a bare purple band with circles was
   appearing at the top of every page whose hero zone had no content. Test
   instead for "has no child other than the decor". */
#TemplateAlert:empty,
#TemplateTitle:empty,
#TemplateAside:has(.side-aside-inner:empty),
#TemplateSectionHero:has(.section-hero-inner:empty),
.template-highlight-inline:empty { display: none; }

#TemplateHero:not(:has(> *:not(.mz-hero-decor))) { display: none; }
/* Belt and braces for browsers without :has() -- if the zone carries nothing
   but the decor span, it collapses to zero height rather than showing a band.
   Browsers that do support :has() hit the rule above first. */
#TemplateHero { padding-block: 0; }
#TemplateHero:has(> *:not(.mz-hero-decor)) {
  padding-block: clamp(1.8rem, 4vw, 2.9rem) clamp(2rem, 4.2vw, 3rem);
}


/* 04 - Keyline, header, top nav ------------------------------------------- */
.mz-keyline { display: flex; height: var(--mz-keyline); }
.mz-keyline span { flex: 1; }
.mz-keyline span:nth-child(1) { background: var(--mz-red); }
.mz-keyline span:nth-child(2) { background: var(--mz-orange); }
.mz-keyline span:nth-child(3) { background: var(--mz-yellow); }
.mz-keyline span:nth-child(4) { background: var(--mz-green); }
.mz-keyline span:nth-child(5) { background: var(--mz-blue); }
.mz-keyline span:nth-child(6) { background: var(--mz-purple); }

.site-header {
  background: var(--mz-card);
  border-bottom: 1px solid var(--mz-line);
  /* visible so a tall logo may overhang the band (see --mz-logo-drop). */
  overflow: visible;
}
.header-inner {
  display: flex;
  align-items: center;
  gap: clamp(.6rem, 1.6vw, 1.1rem);
  padding-block: clamp(.75rem, 1.6vw, 1.05rem);
}
#TemplateLogo { flex: 0 0 auto; line-height: 0; }
#TemplateLogo img {
  width: auto;
  max-width: var(--mz-logo-w);
  max-height: var(--mz-logo-h);
  /* Hangs below the band only if --mz-logo-drop is raised above 0. */
  margin-bottom: calc(-1 * var(--mz-logo-drop));
  margin-left: var(--mz-logo-nudge);
  position: relative;
  z-index: 2;
}
#TemplateLogo p { margin: 0; }

/* Rail alignment. The logo's left edge, the breadcrumb text, and the footer
   grid all sit on the same line as the left menu's content. Desktop only --
   below 901px the menu is off-canvas, so there is nothing to align to. */
@media (min-width: 901px) {
  .header-inner,
  #TemplateTitle,
  .footer-inner { padding-left: calc(var(--mz-gutter) + var(--mz-rail)); }
}

/* Site name + tagline. An h1..h4 here is the centre's name; a paragraph
   under it is the tagline. */
#TemplateHeaderText { flex: 1 1 auto; min-width: 0; }
#TemplateHeaderText :is(h1, h2, h3, h4) {
  margin: 0;
  font-size: clamp(1.15rem, 2.1vw, 1.5rem);
  letter-spacing: -.01em;
}
#TemplateHeaderText p {
  margin: .1rem 0 0;
  color: var(--mz-faint);
  font-size: .87rem;
  line-height: 1.4;
}

/* Header nav: intentionally sparse -- a phone number and one button. */
.header-nav { flex: 0 0 auto; }
.header-nav :is(ul, ol) { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(.6rem, 1.4vw, 1.15rem); margin: 0; padding: 0; list-style: none; }
.header-nav li { margin: 0; }
.header-nav p { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: clamp(.6rem, 1.4vw, 1.15rem); }
/* Colour, size, and hover come from the shared region rule in section 02. */

/* Buttons. ONE definition covers every button in the skin -- header nav,
   the left menu's search submit, and page content -- so they are identical
   in size, shape, motion, and hover. Wiki markup:
   %button%[[Target | Label]]%%  (directive on its own line).

   Colour comes from --mz-c-ink, which a colour modifier sets and which
   INHERITS. So a button inside any element carrying .mz-red / .mz-green /
   etc. adopts that colour automatically -- mz-note, mz-room, mz-feature,
   mz-step, or anything added later. With no modifier anywhere above it, the
   fallback is the accent purple. */
.button a,
a.button,
.mz-button a,
a.mz-button,
#TemplateNav input[type="submit"],
#TemplateNav form button {
  display: inline-block;
  padding: .62rem 1.25rem;
  border: 0;
  background: var(--mz-c-ink, var(--mz-accent));
  background-image: none;   /* cancels the shared underline sweep */
  color: #fff;
  border-radius: var(--mz-radius-pill);
  font-family: var(--mz-display);
  font-weight: 700;
  font-size: .92rem;
  line-height: 1.3;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(44, 44, 42, .12);
  transition: background-color var(--mz-t) var(--mz-ease),
              box-shadow var(--mz-t) var(--mz-ease),
              transform var(--mz-t) var(--mz-ease);
}
.button a:hover,
a.button:hover,
.mz-button a:hover,
a.mz-button:hover,
#TemplateNav input[type="submit"]:hover,
#TemplateNav form button:hover {
  background: var(--mz-c-deep, var(--mz-accent-hover));
  color: #fff;
  transform: var(--mz-lift);
  box-shadow: 0 4px 10px rgba(44, 44, 42, .16);
}
/* Pressing removes the lift, so the control feels physical. */
.button a:active,
a.button:active,
.mz-button a:active,
#TemplateNav input[type="submit"]:active,
#TemplateNav form button:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(44, 44, 42, .12); }

/* The search submit is narrower than a content button but otherwise identical. */
#TemplateNav input[type="submit"],
#TemplateNav form button { padding: .5rem .95rem; font-size: .82rem; }

/* Ghost variant: %button-ghost%[[... ]]%%  -- tracks the same inherited
   modifier as the filled button, so it is never stranded on purple inside a
   coloured block. */
.button-ghost a,
a.button-ghost {
  display: inline-block;
  padding: .58rem 1.2rem;
  border: 1.5px solid var(--mz-c, var(--mz-line));
  border-radius: var(--mz-radius-pill);
  background-image: none;
  color: var(--mz-c-ink, var(--mz-body));
  font-family: var(--mz-display);
  font-weight: 600;
  font-size: .92rem;
  line-height: 1.3;
  text-decoration: none;
  transition: border-color var(--mz-t) var(--mz-ease),
              color var(--mz-t) var(--mz-ease),
              background-color var(--mz-t) var(--mz-ease),
              transform var(--mz-t) var(--mz-ease);
}
.button-ghost a:hover,
a.button-ghost:hover {
  border-color: var(--mz-c-ink, var(--mz-accent));
  color: var(--mz-c-deep, var(--mz-accent));
  background-color: #fff;
  transform: var(--mz-lift);
}
.button-ghost a:active { transform: translateY(0); }


/* 05 - Alert + breadcrumb + hero ------------------------------------------ */
.template-alert {
  margin-block: .9rem;
  padding: .85rem 1.1rem;
  background: var(--mz-yellow-soft);
  border-left: var(--mz-bar) solid var(--mz-yellow);
  border-radius: var(--mz-radius);
  color: var(--mz-yellow-deep);
}
.template-alert :is(p, h1, h2, h3, h4) { margin: 0; }

/* Breadcrumb. The gap above (to the header) and below (to the content boxes)
   both come from --mz-title-gap, so the strip sits optically centred. The
   paragraph's own default 1em margins are reset -- the bottom one used to
   collapse out of the box and add itself to the wrapper's padding, which is
   why there was ~10px more space below the text than above it. */
#TemplateTitle {
  padding-top: var(--mz-title-gap);
  padding-bottom: 0;
  color: var(--mz-faint);
  font-size: .85rem;
}
#TemplateTitle :is(p, ul, ol) { margin: 0; }
#TemplateTitle :is(h1, h2, h3) { font-size: .85rem; margin: 0; color: var(--mz-faint); font-family: var(--mz-font); font-weight: 400; }
#TemplateTitle a { color: var(--mz-faint); }
#TemplateTitle a:hover { color: var(--mz-accent); }

/* The welcome band. Sits at the top of the main white box, edge to edge.

   The three decorative circles are REAL elements (.mz-hero-decor in the tmpl)
   sitting behind the text, not ::before/::after on this section. Axe cannot
   compute contrast through a pseudo-element on an ancestor, so with the old
   approach every line of hero text came back as "needs manual review" on
   every scan. Editors still never touch them -- they live in the template. */
.template-hero {
  position: relative;
  overflow: hidden;
  padding-inline: var(--mz-copy-inset);
  background: var(--mz-purple-soft);
}
.mz-hero-decor {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.mz-hero-decor i {
  position: absolute;
  display: block;
  border-radius: 50%;
}
.mz-hero-decor i:nth-child(1) {
  top: -3.2rem; right: -1.9rem;
  width: clamp(7rem, 16vw, 11.5rem); aspect-ratio: 1;
  background: var(--mz-yellow);
}
.mz-hero-decor i:nth-child(2) {
  bottom: -3.5rem; right: 5.5rem;
  width: clamp(5.5rem, 12vw, 9rem); aspect-ratio: 1;
  background: #9FE1CB;
}
.mz-hero-decor i:nth-child(3) {
  top: 1.5rem; right: clamp(9rem, 15vw, 12.5rem);
  width: clamp(2rem, 4vw, 2.75rem); aspect-ratio: 1;
  background: #F7C1C1;
}
.template-hero > *:not(.mz-hero-decor) { position: relative; z-index: 1; }
.template-hero :is(h1, h2, h3) {
  margin: 0 0 .6rem;
  max-width: 24ch;
  font-size: clamp(1.6rem, 3.4vw, 2.15rem);
  line-height: 1.2;
  color: var(--mz-purple-deep);
}
.template-hero p {
  margin: 0 0 1.1rem;
  max-width: 46ch;
  color: var(--mz-purple-ink);
  font-size: clamp(.95rem, 1.2vw, 1.05rem);
}
.template-hero p:last-child { margin-bottom: 0; }

/* Highlight card (Site.TemplateHighlight) shown inline above page content. */
.template-highlight-inline { padding: 0 var(--mz-copy-inset); }
.template-highlight-inline .mz-highlight,
#TemplateAside .mz-highlight {
  margin: 1.1rem 0 0;
  padding: .95rem 1.1rem;
  background: var(--mz-purple-soft);
  border-radius: var(--mz-radius);
}
.template-highlight-inline .mz-highlight :is(p, h1, h2, h3, h4) { margin: 0; color: var(--mz-purple-deep); font-size: .95rem; }
.template-highlight-inline .mz-highlight strong {
  display: block;
  color: var(--mz-purple-ink);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}


/* 06 - Left nav + aside ---------------------------------------------------- */
#TemplateNav { padding: var(--mz-navcard-pad); }

/* Search box: put (:searchbox:) as the FIRST line of Site.TemplateNav. */
#TemplateNav :is(form, div.search, div.searchbox) { margin: 0 0 .9rem; display: flex; gap: .4rem; }
#TemplateNav input[type="text"],
#TemplateNav input[type="search"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: .5rem .8rem;
  border: 1.5px solid var(--mz-line);
  border-radius: var(--mz-radius-pill);
  background: var(--mz-canvas);
  font-family: inherit;
  font-size: .88rem;
  color: var(--mz-ink);
}
#TemplateNav input[type="text"]:focus,
#TemplateNav input[type="search"]:focus { border-color: var(--mz-accent); background: #fff; }
#TemplateNav input[type="submit"],
#TemplateNav form button {
  flex: 0 0 auto;
  padding: .5rem .9rem;
  border: 0;
  border-radius: var(--mz-radius-pill);
  background: var(--mz-accent);
  color: #fff;
  font-family: var(--mz-display);
  font-weight: 700;
  font-size: .82rem;
  cursor: pointer;
}
#TemplateNav input[type="submit"]:hover,
#TemplateNav form button:hover { background: var(--mz-accent-hover); }

/* Section label above the menu list. */
#TemplateNav :is(h1, h2, h3, h4) {
  margin: 0 0 .5rem;
  padding-inline: var(--mz-item-pad) 0;
  color: var(--mz-faint);
  font-family: var(--mz-font);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
#TemplateNav hr { display: none; }
#TemplateNav .vspace { margin-top: .35rem; }
#TemplateNav .vspace:first-child { display: none; }
#TemplateNav :is(ul, ol) { margin: 0; padding: 0; list-style: none; }
#TemplateNav li { margin: 0; list-style: none; }

#TemplateNav :is(a, .selflink) {
  position: relative;
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 36px;
  /* Rows pull back through the card padding so their pill reaches the card
     edge on the right, while their text stays on the shared inset. */
  margin-right: calc(-1 * var(--mz-navcard-pad));
  padding: .42rem var(--mz-navcard-pad) .42rem var(--mz-item-pad);
  border-radius: var(--mz-radius-pill) 0 0 var(--mz-radius-pill);
  color: var(--mz-muted);
  font-size: .92rem;
  text-decoration: none;
  transition: background-color var(--mz-t) var(--mz-ease),
              color var(--mz-t) var(--mz-ease),
              padding-left var(--mz-t) var(--mz-ease);
}
/* Rows nudge right on hover -- the same 1px-scale motion as a button's lift,
   turned sideways to suit a list. */
#TemplateNav :is(a, .selflink):hover {
  background: var(--mz-canvas);
  color: var(--mz-ink);
  padding-left: calc(var(--mz-item-pad) + 3px);
}

/* THE RAINBOW BULLET.
   Note for anyone porting from the Kin skins: there, ::before on a nav link
   is the square indent bullet and only applies to nested items or lists that
   follow a heading. Here it applies at EVERY level -- top-level items get the
   full-size rainbow dot, nested items get a smaller one in the parent's hue.
   Colours cycle every six items, so a seventh menu item restarts at red. */
#TemplateNav :is(ul, ol) > li > :is(a, .selflink)::before {
  content: "";
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--mz-dot, var(--mz-red));
  /* Pin to the first line so wrapped labels keep the dot beside line one. */
  align-self: flex-start;
  margin-top: calc(.82em - 5.5px);
}
#TemplateNav :is(ul, ol) > li:nth-child(6n + 1) { --mz-dot: var(--mz-red); }
#TemplateNav :is(ul, ol) > li:nth-child(6n + 2) { --mz-dot: var(--mz-orange); }
#TemplateNav :is(ul, ol) > li:nth-child(6n + 3) { --mz-dot: var(--mz-yellow); }
#TemplateNav :is(ul, ol) > li:nth-child(6n + 4) { --mz-dot: var(--mz-green); }
#TemplateNav :is(ul, ol) > li:nth-child(6n + 5) { --mz-dot: var(--mz-blue); }
#TemplateNav :is(ul, ol) > li:nth-child(6n + 6) { --mz-dot: var(--mz-purple); }

/* Nested levels: smaller dot, inherited hue, stepped indent. */
#TemplateNav :is(ul ul, ol ol, li li) > li > :is(a, .selflink) { padding-left: calc(var(--mz-item-pad) + 1.1rem); font-size: .87rem; }
#TemplateNav :is(ul ul, ol ol, li li) > li > :is(a, .selflink)::before { width: 7px; height: 7px; margin-top: calc(.82em - 3.5px); }
#TemplateNav :is(ul ul ul, li li li) > li > :is(a, .selflink) { padding-left: calc(var(--mz-item-pad) + 2.1rem); }
/* Nested items keep the parent's colour rather than restarting the cycle. */
#TemplateNav :is(ul ul, ol ol, li li) > li { --mz-dot: inherit; }

/* Active row: white pill on the canvas-tinted card, dot keeps its colour. */
#TemplateNav :is(.selflink, a.selflink, li.current > a, li.active > a, a[aria-current="page"]) {
  background: var(--mz-canvas);
  color: var(--mz-ink);
  font-weight: 700;
}

/* Aside box under the menu. */
#TemplateAside .side-aside-inner { padding: var(--mz-navcard-pad); }
#TemplateAside :is(h1, h2, h3, h4) {
  margin: 0 0 .5rem;
  color: var(--mz-faint);
  font-family: var(--mz-font);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
#TemplateAside p { margin: 0 0 .5rem; font-size: .86rem; line-height: 1.6; }
#TemplateAside p:last-child { margin-bottom: 0; }
#TemplateAside .mz-highlight { margin-top: 0; }
#TemplateAside iframe { width: 100%; }

#TemplateSectionHero .section-hero-inner { padding: var(--mz-navcard-pad); }


/* 07 - Content column ----------------------------------------------------- */
#TemplateMain { padding: clamp(1.2rem, 2.6vw, 1.8rem) var(--mz-copy-inset) clamp(1.5rem, 3vw, 2.2rem); }
#TemplateMain > :first-child { margin-top: 0; }
#TemplateMain > :last-child { margin-bottom: 0; }

/* Heading colour system: h1 / h3 / h5 near-black, h2 / h4 in the accent
   purple. Block headings inside .mz-note and .mz-room override both (their
   rule is more specific) so a callout's heading always matches its colour. */
#TemplateMain :is(h1, h3, h5) { color: var(--mz-ink); }
#TemplateMain :is(h2, h4) { color: var(--mz-heading-alt); }

#TemplateMain h1 {
  position: relative;
  font-size: clamp(1.5rem, 2.8vw, 1.95rem);
  margin: 0 0 1rem;
  padding-bottom: .6rem;
}
/* The eye candy: a six-segment rainbow bar under the page title, echoing the
   keyline at the top of the page and the strip above the footer. Hard colour
   stops rather than a blend, so it reads as the same device. */
#TemplateMain h1::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 92px;
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(90deg,
    var(--mz-red)    0    16.66%,
    var(--mz-orange) 16.66% 33.33%,
    var(--mz-yellow) 33.33% 50%,
    var(--mz-green)  50%   66.66%,
    var(--mz-blue)   66.66% 83.33%,
    var(--mz-purple) 83.33% 100%);
}
/* Callout headings keep their own colour and take no bar. */
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) h1::after { display: none; }

#TemplateMain h2 { font-size: clamp(1.22rem, 2.1vw, 1.45rem); margin: 1.9rem 0 .65rem; }
#TemplateMain h3 { font-size: clamp(1.05rem, 1.7vw, 1.18rem); margin: 1.5rem 0 .5rem; }
#TemplateMain h4 { font-size: 1rem; margin: 1.2rem 0 .4rem; }
#TemplateMain h5 { font-size: .93rem; margin: 1rem 0 .35rem; letter-spacing: .01em; }

/* Section kicker: a small uppercase label above a group of blocks.

   Prefer making it a real heading so the document outline has no gaps:
     !!%mz-kicker%Our rooms%%          <- h2, looks identical
   A bare  %mz-kicker%Our rooms%%  still works where a label genuinely isn't
   a section heading. When the span is a heading's only child, the heading's
   own type styles stand down and the span supplies the look. */
#TemplateMain .mz-kicker,
#TemplateMain p > .mz-kicker {
  display: block;
  margin: 1.9rem 0 .85rem;
  color: var(--mz-faint);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
}
#TemplateMain :is(h1, h2, h3, h4, h5, h6):has(> .mz-kicker:only-child) {
  margin: 0;
  padding: 0;
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
}
#TemplateMain :is(h1, h2, h3, h4, h5, h6):has(> .mz-kicker:only-child)::after { display: none; }
#TemplateMain p:has(> .mz-kicker:only-child) { margin: 0; }

#TemplateMain p { margin: 0 0 1rem; }
#TemplateMain .mz-lead { font-size: clamp(1.02rem, 1.3vw, 1.15rem); line-height: 1.6; color: var(--mz-muted); }

#TemplateMain :is(ul, ol) { margin: 0 0 1rem; padding-left: 1.35rem; }
#TemplateMain li { margin: .25rem 0; }

#TemplateMain table { border-collapse: collapse; width: 100%; margin: 0 0 1rem; }
#TemplateMain :is(td, th) { padding: .5rem .65rem; border-bottom: 1px solid var(--mz-line); text-align: left; vertical-align: top; }
#TemplateMain th { font-family: var(--mz-display); color: var(--mz-ink); }


/* 08 - Content blocks ----------------------------------------------------- */
/* THE core pattern. .mz-note is a callout; .mz-room adds an icon badge and a
   status tag. Both take any colour modifier (.mz-red ... .mz-purple) and both
   fall back to purple if none is given.

     (:div class="mz-note mz-blue":)
     Text here.
     (:divend:)
*/
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) {
  margin: 0 0 .6rem;
  padding: .95rem 1.15rem;
  background: var(--mz-c-soft, var(--mz-purple-soft));
  border-left: var(--mz-bar) solid var(--mz-c, var(--mz-purple));
  border-radius: var(--mz-radius);
  color: var(--mz-c-ink, var(--mz-purple-ink));
}
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) > :first-child { margin-top: 0; }
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) > :last-child { margin-bottom: 0; }
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) :is(h1, h2, h3, h4, h5) {
  margin: 0 0 .18rem;
  color: var(--mz-c-deep, var(--mz-purple-deep));
  font-size: 1.02rem;
}
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) p { margin: 0 0 .35rem; font-size: .9rem; line-height: 1.6; }
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) p:last-child { margin-bottom: 0; }
/* Links inside ANY element carrying a colour modifier -- note, room, feature,
   step, or anything added later. The block's body text is already
   --mz-c-ink, so a link tinted the same colour was invisible. Links take the
   DEEP tone and carry an underline, distinguishing them by two channels
   rather than colour alone (WCAG 1.4.1). */
#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) a {
  color: var(--mz-c-deep, var(--mz-accent));
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-decoration-color: var(--mz-c, var(--mz-accent));
}
#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) a:hover {
  text-decoration-color: currentColor;
}

/* Buttons inside a coloured block already take the block's colour from the
   inherited variable (section 04). This rule only protects the label: the
   link rule above would otherwise repaint white button text to the same
   colour as the fill and hide it. */
#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) :is(.button, .mz-button) a {
  color: #fff;
  font-weight: 700;
  text-decoration: none;
}
#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) :is(.button, .mz-button) a:hover { color: #fff; }

#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) .button-ghost a {
  color: var(--mz-c-ink, var(--mz-body));
  font-weight: 600;
  text-decoration: none;
}
#TemplateMain :is(.mz-red, .mz-orange, .mz-yellow, .mz-green, .mz-blue, .mz-purple, .mz-teal) .button-ghost a:hover {
  color: var(--mz-c-deep, var(--mz-accent));
}

/* Last block in a run gets its bottom margin back. */
#TemplateMain :is(.mz-note, .mz-room, .mz-contact) + :not(.mz-note, .mz-room, .mz-contact) { margin-top: 1.5rem; }

/* Pinned notice: a small kicker line above the title.
   Wiki markup:  %mz-pin%PINNED%%  as the first line inside the block. */
#TemplateMain .mz-pin {
  display: block;
  margin-bottom: .15rem;
  color: var(--mz-c-ink, var(--mz-teal-ink));
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* Room / contact block: an icon badge on the left, a status tag right-aligned
   on the title line.

   The BADGE IS THE IMAGE ITSELF, not its wrapper. PmWiki does not reliably
   put an Attach: image in its own <p> -- depending on surrounding markup it
   may emit the <img> as a direct child of the div, and a rule targeting
   `p:has(img)` then matches nothing, dropping the icon into the flow above
   the text. Styling the <img> works for every shape, since the block is the
   nearest positioned ancestor either way. */
#TemplateMain :is(.mz-room, .mz-contact) {
  position: relative;
  padding-left: 4.15rem;
  min-height: 4.4rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
#TemplateMain :is(.mz-room, .mz-contact) img {
  position: absolute;
  left: 1.05rem;
  top: 50%;
  /* Centred with the standalone `translate` property, NOT transform. The
     zoom opt-out rule below sets transform:none on images inside these
     blocks, which would silently cancel a transform-based centring; and a
     negative margin is dropped when the image happens to be a direct flex
     child. `translate` is independent of both. */
  translate: 0 -50%;
  box-sizing: border-box;
  width: 40px;
  height: 40px;
  padding: 9px;
  background: #fff;
  border-radius: 50%;
  object-fit: contain;
}
/* Whatever wrapper the image happens to land in must not reserve space for
   it -- the image is out of flow. Harmless when there is no wrapper. */
#TemplateMain :is(.mz-room, .mz-contact) p:has(> img:only-child) { margin: 0; }
#TemplateMain :is(.mz-room, .mz-contact):not(:has(img)) { padding-left: 1.15rem; }

/* Status tag, sits hard right on the heading line:
     !!!! Infant room %mz-tag%2 spaces%%  */
#TemplateMain :is(.mz-room, .mz-contact) :is(h3, h4, h5):has(.mz-tag) { display: flex; align-items: baseline; gap: .8rem; }
#TemplateMain .mz-tag {
  margin-left: auto;
  flex: 0 0 auto;
  padding: .2rem .7rem;
  background: #fff;
  border-radius: var(--mz-radius-pill);
  color: var(--mz-c-ink, var(--mz-muted));
  font-family: var(--mz-font);
  font-size: .72rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Contact rows. Identical machinery to .mz-room -- icon badge, tinted body,
   left colour bar -- but the detail line is the important part rather than
   the heading, so the two swap weight. Links inside stay underlined by the
   coloured-block link rule, so a phone or email link is unmistakable. */
#TemplateMain .mz-contact :is(h3, h4, h5) {
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  opacity: .85;
}
#TemplateMain .mz-contact p { font-size: 1.02rem; line-height: 1.5; }
#TemplateMain .mz-contact p a { font-weight: 700; }

/* Call-to-action block: a note with the button pushed to the right. */
#TemplateMain .mz-cta { border-radius: var(--mz-radius-lg); padding: 1.15rem 1.3rem; }
@media (min-width: 620px) {
  #TemplateMain .mz-cta { display: flex; align-items: center; gap: 1.2rem; }
  #TemplateMain .mz-cta > :is(h1, h2, h3, h4, p):not(:has(.button)) { flex: 1 1 auto; }
  #TemplateMain .mz-cta p:has(.button) { flex: 0 0 auto; margin: 0; }
  #TemplateMain .mz-cta :is(h3, h4) { flex-basis: 100%; }
}
#TemplateMain .mz-cta:has(> :is(h3, h4)) { flex-wrap: wrap; }

/* Bulleted item list, using the same rainbow dots as the menu.
     (:div class="mz-list":)
     * '''Title''' \\
       Description
     (:divend:)                                                          */
#TemplateMain .mz-list ul { margin: 0; padding: 0; list-style: none; }
#TemplateMain .mz-list li {
  position: relative;
  margin: 0;
  padding: 0 0 .85rem 1.4rem;
  border-bottom: 1px solid var(--mz-line);
}
#TemplateMain .mz-list li + li { padding-top: .85rem; }
#TemplateMain .mz-list li:last-child { border-bottom: 0; padding-bottom: 0; }
#TemplateMain .mz-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .55em;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--mz-dot, var(--mz-red));
}
#TemplateMain .mz-list li + li::before { top: 1.4em; }
#TemplateMain .mz-list li:nth-child(6n + 1) { --mz-dot: var(--mz-red); }
#TemplateMain .mz-list li:nth-child(6n + 2) { --mz-dot: var(--mz-orange); }
#TemplateMain .mz-list li:nth-child(6n + 3) { --mz-dot: var(--mz-yellow); }
#TemplateMain .mz-list li:nth-child(6n + 4) { --mz-dot: var(--mz-green); }
#TemplateMain .mz-list li:nth-child(6n + 5) { --mz-dot: var(--mz-blue); }
#TemplateMain .mz-list li:nth-child(6n + 6) { --mz-dot: var(--mz-purple); }
#TemplateMain .mz-list strong { display: block; color: var(--mz-ink); font-family: var(--mz-display); font-size: 1.02rem; }

/* Three-across feature row with circular icon badges.
     (:div class="mz-features":)
     (:div1 class="mz-feature mz-red":) Attach:heart.svg
     !!!! Warm care
     Educators who know your child by name.
     (:div1end:)
     ...
     (:divend:)                                                          */
#TemplateMain .mz-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(1rem, 2.2vw, 1.6rem);
  margin: 1.6rem 0;
}
#TemplateMain .mz-feature { text-align: center; }
/* Same wrapper-independence as the room/contact badge above: style the image,
   not whatever element PmWiki happened to wrap it in. */
#TemplateMain .mz-feature img {
  box-sizing: border-box;
  width: 58px;
  height: 58px;
  padding: 16px;
  margin: 0 auto .7rem;
  display: block;
  background: var(--mz-c-soft, var(--mz-purple-soft));
  border-radius: 50%;
  object-fit: contain;
}
#TemplateMain .mz-feature p:has(> img:only-child) { margin: 0; }
#TemplateMain .mz-feature :is(h3, h4) { margin: 0 0 .25rem; font-size: 1rem; }
#TemplateMain .mz-feature p { margin: 0; font-size: .87rem; line-height: 1.6; color: var(--mz-muted); }

/* Daily rhythm strip: four columns, each with a coloured top rule.
     (:div class="mz-steps":)
     (:div1 class="mz-step mz-red":) 7:00 \\ Arrival, free play (:div1end:)
     ...                                                                 */
#TemplateMain .mz-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: clamp(.9rem, 2vw, 1.3rem);
  margin: 1.4rem 0;
}
#TemplateMain .mz-step { border-top: 5px solid var(--mz-c, var(--mz-purple)); padding-top: .6rem; }
#TemplateMain .mz-step p { margin: 0; font-size: .92rem; color: var(--mz-ink); }
#TemplateMain .mz-step p:first-child { color: var(--mz-faint); font-size: .8rem; margin-bottom: .15rem; }

/* At-a-glance fact table (works in the aside or in the content column).
     (:div class="mz-facts":)
     || Ages || 6 mo - 5 yr ||
     (:divend:)                                                          */
.mz-facts {
  background: var(--mz-canvas);
  border-radius: var(--mz-radius);
  padding: .85rem 1rem;
}
#TemplateAside .mz-facts { padding: .75rem .85rem; }
.mz-facts table { width: 100%; border-collapse: collapse; margin: 0; }
.mz-facts :is(td, th) {
  padding: .2rem 0;
  border: 0;
  font-size: .84rem;
  line-height: 1.9;
  color: var(--mz-muted);
  text-align: left;
}
.mz-facts :is(td, th) + :is(td, th) { text-align: right; color: var(--mz-ink); }

/* --- Image zoom ---------------------------------------------------------

   Applies to content images ONLY -- everything inside #TemplateMain except
   the icon blocks, which are 22-26px glyphs that must not react. No class is
   needed on ordinary images; the exclusions below are the opt-outs.

   Two behaviours, layered:

   1. NO JAVASCRIPT (default). A zoom-in cursor plus a modest lift-and-scale
      on hover or keyboard focus. PmWiki already wraps a thumbnail in a link
      to the full-size file, so clicking opens the full image -- which is
      accessible, needs nothing, and works in every browser.

   2. WITH mzelc-zoom.js (opt-in, see $TemplateSkin['ImageZoom']). Clicking
      opens the image in a <dialog> overlay instead of navigating away.

   Why not scale the image in place on click: .content-card is overflow:hidden
   (it has to be, to clip the hero band to the rounded corners), so an image
   scaled past the card's edge is simply cut off. Anything larger than a small
   nudge has to escape the card, which means an overlay. */

/* The zoom-in cursor appears ONLY where clicking actually does something:
   an image inside a link (which opens the full file with no JavaScript at
   all), or an image the optional script has wrapped in a .mz-zoom-trigger
   button. A bare image with the script switched off is not clickable, so it
   must not advertise that it is. */
#TemplateMain a img,
#TemplateMain .mz-zoom-trigger img {
  cursor: zoom-in;
  transition: transform var(--mz-t) var(--mz-ease),
              box-shadow var(--mz-t) var(--mz-ease);
}
#TemplateMain a:hover img,
#TemplateMain a:focus-visible img,
#TemplateMain .mz-zoom-trigger:hover img,
#TemplateMain .mz-zoom-trigger:focus-visible img {
  transform: scale(1.02);
  box-shadow: var(--mz-shadow-lift);
}

/* The button the script wraps around a bare image: a pure wrapper, so it must
   not look like a button. It keeps its focus ring from the global
   :focus-visible rule. */
#TemplateMain .mz-zoom-trigger {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: zoom-in;
  max-width: 100%;
}
#TemplateMain .mz-card .mz-zoom-trigger { width: 100%; }

/* Opt-outs. Icon glyphs inside the block patterns, plus an explicit
   .mz-nozoom for any image an editor doesn't want treated as zoomable:
     (:div class="mz-nozoom":)
     Attach:diagram.png"A diagram"
     (:divend:)                                                          */
#TemplateMain :is(.mz-room, .mz-contact, .mz-feature, .mz-step, .mz-nozoom) :is(img, a:hover img) {
  cursor: inherit;
  transform: none;
  box-shadow: none;
}

/* Staff / poster cards. Optional layout for a headshot beside a bio:
     (:div class="mz-card mz-green":)
     Attach:jane.jpg"Jane Doe"
     !!! Jane Doe
     Room lead, infants. Eleven years with us.
     (:divend:)

   Float rather than grid. PmWiki emits the image and the text as flat
   siblings, so a grid needs the image to span N rows -- and any fixed N
   either clips a long bio or, if generous, pads the card with empty rows.
   A float needs no row maths: the text wraps beside the image, and the
   clearfix makes the card exactly as tall as whichever is taller. */
#TemplateMain .mz-card {
  margin: 0 0 1.1rem;
  padding: 1.1rem 1.25rem;
  background: var(--mz-c-soft, var(--mz-canvas));
  border-left: var(--mz-bar) solid var(--mz-c, var(--mz-purple));
  border-radius: var(--mz-radius);
}
#TemplateMain .mz-card::after { content: ""; display: table; clear: both; }
#TemplateMain .mz-card p:has(img) {
  float: left;
  width: clamp(110px, 26%, 190px);
  margin: 0 clamp(1rem, 2.4vw, 1.5rem) .5rem 0;
}
#TemplateMain .mz-card img {
  width: 100%;
  border-radius: calc(var(--mz-radius) - 4px);
  display: block;
}
#TemplateMain .mz-card :is(h2, h3, h4) { margin: 0 0 .2rem; color: var(--mz-c-deep, var(--mz-ink)); }
#TemplateMain .mz-card p { margin: 0 0 .4rem; font-size: .92rem; color: var(--mz-c-ink, var(--mz-muted)); }
#TemplateMain .mz-card p:last-child { margin-bottom: 0; }
@media (max-width: 620px) {
  #TemplateMain .mz-card p:has(img) { float: none; width: 100%; max-width: 190px; }
}

/* Grid of cards, for a full careers or staff page. Photo on top here. */
#TemplateMain .mz-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: clamp(.9rem, 2vw, 1.3rem);
  margin: 1.4rem 0;
}
#TemplateMain .mz-card-grid .mz-card { margin: 0; }
#TemplateMain .mz-card-grid .mz-card p:has(img) { float: none; width: 100%; margin: 0 0 .7rem; }

/* Overlay used by mzelc-zoom.js. Styled here so the script stays tiny and
   carries no inline CSS. A native <dialog> brings the focus trap, Esc to
   close, inertness of the page behind, and correct roles for free. */
.mz-zoom-dialog {
  max-width: 94vw;
  max-height: 94vh;
  padding: 0;
  border: 0;
  border-radius: var(--mz-radius);
  background: transparent;
  overflow: visible;
}
.mz-zoom-dialog::backdrop { background: rgba(44, 44, 42, .82); }
.mz-zoom-dialog img {
  display: block;
  max-width: 94vw;
  max-height: 84vh;
  width: auto;
  height: auto;
  border-radius: var(--mz-radius);
  background: var(--mz-card);
}
.mz-zoom-dialog figcaption {
  margin: .6rem auto 0;
  padding: .4rem .9rem;
  max-width: max-content;
  /* Solid, not the translucent backdrop. White on the backdrop is genuinely
     fine (7.36:1 over a white page), but axe cannot resolve contrast through
     a semi-transparent ::backdrop and reports it as a failure. An opaque
     panel makes the ratio computable -- and 13.99:1 rather than borderline. */
  background: var(--mz-ink);
  border-radius: var(--mz-radius-pill);
  color: #fff;
  font-size: .85rem;
  text-align: center;
}
.mz-zoom-close {
  position: absolute;
  top: -.6rem;
  right: -.6rem;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--mz-card);
  color: var(--mz-ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--mz-shadow-lift);
}
.mz-zoom-close:hover { background: var(--mz-canvas); }
/* Responsive 16:9 wrapper for a video or map. */
#TemplateMain .mz-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  margin: 1.5rem 0;
  border-radius: var(--mz-radius);
  overflow: hidden;
  background: #000;
}
#TemplateMain .mz-embed :is(iframe, video, object, embed) { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }


/* 09 - Footer / bottom ---------------------------------------------------- */
.site-footer {
  margin-top: clamp(1rem, 2vw, 1.6rem);
  background: var(--mz-card);
  border-top: 1px solid var(--mz-line);
}
.footer-inner { padding-block: clamp(1.4rem, 3vw, 2.2rem); }

/* Page action / edit links, sitting ABOVE the footer grid. Normally wrapped
   in an editor-only conditional, so most visitors never see them:

     (:if auth edit:)
     (:div class="mz-editlinks":)
     * [[{*$FullName}?action=edit | Edit this page]]
     * [[{*$FullName}?action=diff | History]]
     (:divend:)
     (:ifend:)

   {*$FullName} -- the STARRED form -- is required inside template pages, or
   every link points at Site.TemplateFooter rather than the page being viewed.

   These deliberately look identical to the other footer links: same muted
   colour, same size, no underline until hover, same sweep. They are laid out
   inline rather than stacked, and PmWiki emits one <ul> per contiguous run of
   list items, so two separate runs are handled too. */
.mz-editlinks {
  margin: 0 0 clamp(1.1rem, 2.2vw, 1.6rem);
  padding: 0 0 clamp(.9rem, 1.8vw, 1.2rem);
  border-bottom: 1px solid var(--mz-line);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem clamp(.9rem, 2vw, 1.5rem);
}
.mz-editlinks :is(ul, ol) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem clamp(.9rem, 2vw, 1.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
.mz-editlinks li { margin: 0; list-style: none; }
.mz-editlinks p {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem clamp(.9rem, 2vw, 1.5rem);
}
/* .mz-editlinks styles LAYOUT ONLY -- the inline row and the divider rule.
   Link colour, size, and hover come from the region rule in section 02, so
   these links match the rest of the footer even if this wrapper is missing.
   Without the wrapper they simply stack instead of sitting on one row. */
.mz-editlinks .vspace { margin: 0; }

/* DIVIDER FALLBACK -- works with no wrapper class at all.
   PmWiki action links always carry ?action=... in the href, so the footer can
   detect that page-action links are present (i.e. an editor is logged in) and
   put the divider on TOP of the footer grid instead. Logged-out visitors have
   no action links, so no stray line appears.

   The guards mean this only applies when NO other divider is already being
   drawn -- neither the wrapper's own border-bottom nor a manual ---- rule --
   so exactly one line appears however the footer is marked up. */
.footer-inner:has(a[href*="action="]):not(:has(.mz-editlinks)):not(:has(hr)) .mz-footer-grid {
  border-top: 1px solid var(--mz-line);
  padding-top: clamp(1.1rem, 2.2vw, 1.6rem);
}

/* If an editor adds BOTH the wrapper and a manual ---- rule, the manual one
   wins and the wrapper's own border stands down, so there is still one line. */
.mz-editlinks:has(~ hr) { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }

/* Manual divider. An editor can type ---- on its own line in
   Site.TemplateFooter to place the separator explicitly, which is the most
   reliable option of all -- it needs neither a wrapper class nor :has(). */
.site-footer hr {
  margin: clamp(.9rem, 1.8vw, 1.2rem) 0 clamp(1.1rem, 2.2vw, 1.6rem);
  height: 1px;
  border: 0;
  /* Solid edge to edge here, not the fading rule used in page content -- as
     a structural divider it should read as a clean break across the column. */
  background: var(--mz-line);
}

.mz-footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: clamp(1.2rem, 3vw, 2.4rem); }
.mz-footer-grid :is(h3, h4) {
  margin: 0 0 .55rem;
  color: var(--mz-faint);
  font-family: var(--mz-font);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
/* List reset covers the WHOLE footer, so a link list that isn't wrapped in a
   div still renders as clean bullet-less links rather than a bulleted list. */
.site-footer :is(ul, ol) { margin: 0; padding: 0; list-style: none; }
.site-footer li { margin: 0 0 .3rem; }
/* Link colour, size, and hover come from the shared region rule in
   section 02, which covers the WHOLE footer -- not just this grid. */
.mz-footer-grid p { margin: 0 0 .3rem; font-size: .88rem; color: var(--mz-muted); }
/* Brand column. The whole footer grid is indented to the rail on desktop, so
   this logo's left edge already lines up with the header logo and the left
   menu's content. It is also centred within its own column band vertically,
   so short brand columns don't leave it stranded at the top. */
.mz-footer-brand { display: flex; flex-direction: column; justify-content: center; }
.mz-footer-brand img { max-width: var(--mz-footer-logo-w); width: 100%; margin-bottom: .7rem; }
.mz-footer-brand p { margin: 0 0 .3rem; }

.template-bottom { background: var(--mz-card); border-top: 1px solid var(--mz-line); }
.bottom-inner { padding-block: .95rem; }
@media (min-width: 901px) {
  .bottom-inner { padding-left: calc(var(--mz-gutter) + var(--mz-rail)); }
}
.mz-bottom-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem 1.5rem;
  color: var(--mz-faint);
  font-size: .8rem;
}
.mz-bottom-grid > div { margin: 0; }
.mz-bottom-grid p { margin: 0; }
/* Credit strip links.

   SIZE: inherit, so links match the surrounding credit text exactly.

   UNDERLINE: a permanent hairline that is always visible, so links are
   identifiable at rest without relying on colour alone, plus the shared
   ::after sweep on top of it for hover. Both are drawn with borders and
   pseudo-elements rather than background gradients, so axe can still resolve
   the element's background and compute contrast. */
.template-bottom a {
  font-size: inherit;
  color: var(--mz-faint);
  border-bottom: 1px solid var(--mz-faint);
}
.template-bottom a::after { bottom: -1px; }
.template-bottom a:hover { color: var(--mz-accent); border-bottom-color: transparent; }


/* 10 - Responsive --------------------------------------------------------- */
@media (max-width: 900px) {
  .header-inner { flex-wrap: wrap; row-gap: .55rem; }
  #TemplateHeaderText { flex: 1 1 100%; order: 3; }
  .header-nav { margin-left: auto; }

  /* No CSS 'order' here. The tmpl now puts main before the supplementary
     boxes, so natural document order already gives content first on mobile.
     Reordering visually with 'order' would desynchronise the tab sequence
     from what is on screen. */
  #TemplateSectionHero { margin-top: var(--mz-col-gap); }

  /* The left menu becomes an off-canvas panel sliding in from the left,
     driven entirely by the checkbox in the tmpl -- no JavaScript. */
  .template-nav-toggle {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
  .template-nav-toggle-label {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin-bottom: .9rem;
    padding: .7rem 1rem;
    background: var(--mz-accent);
    color: #fff;
    border-radius: var(--mz-radius-pill);
    font-family: var(--mz-display);
    font-weight: 700;
    font-size: .92rem;
    cursor: pointer;
  }
  .template-nav-toggle-label::before { content: "\2630"; font-size: 1rem; }
  /* When open, this label becomes the fixed close button AND supplies the
     scrim through its own ::after -- so tapping outside the panel still
     closes it, using the one label the checkbox is allowed to have. */
  .template-nav-toggle:checked + .template-nav-toggle-label {
    position: fixed;
    top: .8rem;
    right: .8rem;
    z-index: 130;
    margin: 0;
    width: 44px;
    height: 44px;
    padding: 0;
    justify-content: center;
    border-radius: 50%;
    font-size: 0;                 /* hide the word, keep the accessible name */
  }
  .template-nav-toggle:checked + .template-nav-toggle-label::before {
    content: "\00D7";
    font-size: 1.5rem;
    line-height: 1;
  }
  .template-nav-toggle:checked + .template-nav-toggle-label::after {
    content: "";
    position: fixed;
    inset: 0;
    /* Negative index inside this label's own stacking context: paints behind
       the button itself, and behind the panel because the panel's z-index is
       higher than this label's. */
    z-index: -1;
    background: rgba(44, 44, 42, .45);
    cursor: pointer;
  }
  /* The checkbox itself is off-screen, so its focus ring has to be drawn on
     the label the user can actually see. Without this a keyboard user tabs
     onto the toggle and nothing appears to happen (WCAG 2.4.7). */
  .template-nav-toggle:focus-visible + .template-nav-toggle-label {
    outline: 3px solid var(--mz-focus);
    outline-offset: 3px;
  }

  #TemplateNav {
    position: fixed;
    inset: 0 auto 0 0;
    /* Above the toggle label (130), so the label's ::after scrim paints
       behind the panel rather than over it. */
    z-index: 140;
    width: min(84vw, 320px);
    border-radius: 0 var(--mz-radius) var(--mz-radius) 0;
    box-shadow: var(--mz-shadow-lift);
    overflow-y: auto;
    transform: translateX(-102%);
    /* visibility:hidden is what actually takes the closed panel OUT of the
       tab order. transform alone only moves it off-screen: its search field,
       submit button, and every menu link stayed focusable, so a keyboard user
       tabbed through eight invisible controls (WCAG 2.4.3). The delayed
       transition lets the slide-out animation finish before it hides. */
    visibility: hidden;
    transition: transform .26s var(--mz-ease), visibility 0s linear .26s;
  }
  .template-nav-toggle:checked ~ #TemplateNav {
    transform: translateX(0);
    visibility: visible;
    transition: transform .26s var(--mz-ease), visibility 0s;
  }

  #TemplateNav :is(a, .selflink) { margin-right: 0; border-radius: var(--mz-radius-pill); }
  #TemplateAside { margin-top: var(--mz-col-gap); }
}

@media (max-width: 620px) {
  #TemplateMain :is(.mz-room, .mz-contact) { padding-left: 1.15rem; }
  #TemplateMain :is(.mz-room, .mz-contact) img { position: static; translate: none; margin: 0 0 .5rem; }
  #TemplateMain :is(.mz-room, .mz-contact) p:has(> img:only-child) { margin: 0 0 .5rem; }
  #TemplateMain :is(.mz-room, .mz-contact) :is(h3, h4, h5):has(.mz-tag) { flex-wrap: wrap; gap: .35rem; }
  #TemplateMain .mz-tag { margin-left: 0; }
  .mz-bottom-grid { justify-content: flex-start; }
  .mz-hero-decor i:nth-child(2) { display: none; }
}


/* 11 - Print + reduced motion --------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* The zoom nudge is motion, not information -- drop it entirely. The
     zoom-in cursor and the dialog both still work. */
  #TemplateMain a:hover img,
  #TemplateMain a:focus-visible img,
  #TemplateMain .mz-zoom-trigger:hover img,
  #TemplateMain .mz-zoom-trigger:focus-visible img { transform: none; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media print {
  body { background: #fff; color: #000; }
  .mz-keyline,
  #TemplateTop,
  #TemplateNav,
  #TemplateAside,
  #TemplateBottomNav,
  .template-nav-toggle-label,
  .skip-link { display: none !important; }
  #TemplateWrapper { display: block; padding: 0; }
  .content-card, .side-card { box-shadow: none; border-radius: 0; }
  .template-hero { background: #fff; }
  .mz-hero-decor { display: none; }
  #TemplateMain :is(.mz-note, .mz-room, .mz-contact) { background: #fff; border: 1px solid #999; border-left-width: 4px; }
  #TemplateMain img { cursor: auto; transform: none; box-shadow: none; }
  .mz-zoom-dialog, .mz-zoom-close { display: none !important; }
  a { text-decoration: underline; }
}
