/*
Theme Name:   Millburn Green
Theme URI:    https://millburngreen.org
Description:  Millburn Green. A classic theme -- PHP templates, real nav menus,
              and no Site Editor. Design tokens, typography and CSS foundation
              from the Web & Brand Style Guide v1.0, all defined in files:
              style.css, styleguide-style.css, functions.php, theme.json.
Author:       Net Theory
Version:      1.0.0
Text Domain:  millburn-green
*/

/* ==========================================================================
   THIS FILE IS THE ADDITIONS ONLY.
   --------------------------------------------------------------------------
   The tokens, base reset, heading scale, containers, header, buttons, cards,
   metrics, map and breakpoints all live in styleguide-style.css, which is §21
   of the style guide verbatim and is enqueued ahead of this file.

   Keeping it untouched means a style guide revision can be dropped in whole,
   and any difference between the guide and the site is a real difference
   rather than a transcription error. Everything below is something §21 does
   not cover.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts -- self-hosted, not Google Fonts

   One less third-party dependency at handoff, no visitor IPs sent to Google
   (this is a township-adjacent site), and faster on a cold cache than a second
   DNS lookup plus TLS handshake.

   Both families are VARIABLE: one file covers Montserrat 300-700, so the five
   weights the guide asks for are one download, not five. latin and latin-ext
   are separate faces with unicode-range, so a reader of English never fetches
   latin-ext.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/montserrat-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/montserrat-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/newsreader-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/newsreader-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   Additions
   -------------------------------------------------------------------------- */

:root {
  /* §12 gives the dashboard its own ground; §21 has no token for it. */
  --dashboard-bg: #F2F4F0;
}

body { -webkit-font-smoothing: antialiased; }

/* §11 uses an uppercase eyebrow in several places but defines no class. */
.eyebrow {
  font: 600 12px/1.2 var(--font-ui);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Page heading and its standfirst, as one unit.
   ---------------------------------------------------------------------------
   Alignment is set ONCE here and inherited by both, so they cannot drift apart.
   Add .is-centered to centre the pair; nothing else needs changing.

   The margin-inline: 0 is load-bearing. WordPress's constrained layout gives
   every child auto inline margins, so the moment .subtitle gained a max-width
   it floated to the centre of the column while its text stayed left-aligned --
   which is why it looked centred under a left-aligned H1. */
.page-head { text-align: left; }

/* Standfirst. Body size (16px, §3) rather than the Intro step, so it supports
   the heading instead of competing with it. */
.subtitle {
  margin-top: 10px;
  margin-inline: 0;
  max-width: 62ch;                 /* a measure, so it does not run the full 1360px */
  font: 400 16px/1.6 var(--font-ui);
  color: var(--muted);
}

.page-head.is-centered { text-align: center; }
.page-head.is-centered .subtitle { margin-inline: auto; }

/* §17 defines the resting state of the buttons but no interaction. */
.button { cursor: pointer; transition: background-color .15s ease, color .15s ease; }
.button-primary:hover { background: #10403A; }
.button-secondary:hover { background: rgba(23, 79, 72, .06); }

/* Numbers in a column read wrong without aligned figures. §3 sets the size of
   the dashboard number but not its figures. */
.metric-value { font-variant-numeric: tabular-nums; }

/* Twenty Twenty-Five sets its own root padding and background through
   theme.json; both need to yield to the guide's containers and Warm Cream. */
body .wp-site-blocks { padding-inline: 0; }

/* Skip link, for keyboard users. Not a design question, so not in the guide. */
.mg-skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  padding: 12px 18px;
  background: var(--green-deep);
  color: var(--white);
  font: 600 14px/1 var(--font-ui);
}
.mg-skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Header and footer -- §9, §19

   §21 styles .site-header, .nav and .nav-links; everything below is the parts
   the guide describes in prose but does not provide CSS for.
   -------------------------------------------------------------------------- */

/* The lockup is sized by HEIGHT, not width. The header is a fixed 88px (§9)
   and collapses to 72px when stuck, so height is the constraint; width follows
   from the artwork's 3.34:1 and lands at ~194px, near the ~210px §9 asks for.
   Sizing by width instead would let a future lockup with a different aspect
   ratio silently overflow the header. */
/* One number drives the lockup's height, the separator's height and the
   strapline's leading, so the three cannot fall out of step. */
.site-header { --mark-h: 58px; }
.mg-logo { display: inline-flex; align-items: center; text-decoration: none; }
.mg-logo img { height: var(--mark-h, 58px); width: auto; display: block; }

/* Lockup, hairline, strapline. */
.mg-brand { display: flex; align-items: center; }
.mg-strapline {
  margin: 0 0 0 20px;
  padding-left: 20px;
  /* --green at half strength: a muted green that is still part of the palette
     rather than a fourth grey. The rule is this element's own left border, so
     its height IS the strapline's height -- three lines that total the mark's
     height, which is why it lines up with the lockup exactly and keeps doing
     so if --mark-h changes. */
  border-left: 2px solid rgba(103, 155, 88, .5);
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 400;
  line-height: calc(var(--mark-h, 58px) / 3);
  color: var(--muted);
}

/* The sticky header must clear the WordPress admin bar, which only exists for
   logged-in editors -- so this breaks for exactly the people who maintain the
   site and for nobody else, which is why it is easy to miss. The bar is 32px
   above 782px and 46px below it. */
.site-header { position: sticky; top: 0; z-index: 100; }
.admin-bar .site-header { top: 32px; }
@media (max-width: 782px) { .admin-bar .site-header { top: 46px; } }

/* §9: the sticky variant collapses to 72px. */
.site-header.is-stuck { height: 72px; }
.site-header.is-stuck { --mark-h: 46px; }   /* the strapline follows */

/* Footer -- §19 ------------------------------------------------------------ */
.site-footer { padding-block: 56px 40px; }
.site-footer a { color: var(--cream); text-decoration: none; opacity: .88; }
.site-footer a:hover { opacity: 1; text-decoration: underline; }
.mg-footer-legal {
  /* No top rule, margin or padding any more: this is the whole footer, not a
     strip sitting under the brand and the link columns, so the divider had
     nothing left above it to divide from. */
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 16px 48px;
  justify-content: space-between;
  /* centre, not end: the lockup is 20px and the copyright a line of 13px
     text, so aligning their baselines left the mark sitting low. */
  align-items: center;
}

/* Wordmark, a hairline, then the tagline -- one line on the left. */
.mg-footer-brand { display: flex; align-items: center; gap: 12px; }
.mg-footer-brand .mg-logo img { height: 24px; width: auto; }
/* The rule is a border on the tagline rather than an element of its own: it is
   decoration, and a screen reader should not have to read a pipe character. */
.mg-footer-tagline {
  padding-left: 12px;
  border-left: 1px solid rgba(38, 49, 44, .24);
  font: 400 13px/1.4 var(--font-editorial, Georgia, serif);
  color: var(--muted);
}
.mg-copyright { margin: 0; font-size: 13px; opacity: .68; }

@media (max-width: 640px) {
  .site-header { --mark-h: 46px; }
  /* The strapline stays, scaled down with the mark rather than dropped. Its
     leading is already calc(--mark-h / 3), so the three lines still total the
     lockup's height; only the type and the spacing come in. At 10.5px
     "Environmentally Conscious" measures about 125px, which is what the
     narrowest phone leaves once the lockup and the rule have had theirs. */
  .mg-strapline {
    margin-left: 14px;
    padding-left: 14px;
    font-size: 10.5px;
  }
}

/* The smallest phones still in use -- 320px, an SE or an older Android. At the
   sizes above, "Environmentally Conscious" runs about 125px and the lockup
   leaves it only ~102px, so it wrapped to a fourth line: taller than the mark
   beside it, and taller than the header itself. The mark gives up 6px and the
   spacing 4px either side, which buys the line back. */
@media (max-width: 360px) {
  .site-header { --mark-h: 40px; }
  .mg-strapline {
    margin-left: 10px;
    padding-left: 10px;
    font-size: 10px;
  }
}

/* --------------------------------------------------------------------------
   Mobile navigation -- §21 hides .nav-links below 900px but does not say what
   replaces it.

   A <details> disclosure: no framework, no plugin, and it still opens with
   JavaScript disabled. §23 has five top-level items with children, so the
   panel handles one level of nesting.
   -------------------------------------------------------------------------- */

.mg-nav { display: flex; align-items: center; }
.mg-nav-mobile { display: none; position: relative; }

.nav-links { list-style: none; margin: 0; padding: 0; }
.nav-links li { position: relative; }
.nav-links .sub-menu {
  position: absolute; top: calc(100% + 10px); left: 0;
  display: none; min-width: 210px;
  list-style: none; margin: 0; padding: 8px 0;
  background: var(--white); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: 0 6px 20px rgba(0,0,0,.09);
  z-index: 50;
}
.nav-links li:hover > .sub-menu,
.nav-links li:focus-within > .sub-menu { display: block; }
.nav-links .sub-menu a { display: block; padding: 8px 18px; font-size: 14px; }

@media (max-width: 900px) {
  .mg-nav-mobile { display: block; }

  .mg-nav-mobile summary {
    list-style: none; cursor: pointer;
    width: 40px; height: 40px;
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
  }
  .mg-nav-mobile summary::-webkit-details-marker { display: none; }
  .mg-nav-mobile summary span {
    display: block; height: 2px; width: 24px;
    background: var(--green-deep); border-radius: 2px;
  }

  .mg-nav-panel {
    position: absolute; right: 0; top: calc(100% + 12px);
    min-width: 232px; z-index: 200;
    list-style: none; margin: 0; padding: 10px 0;
    background: var(--white); border: 1px solid var(--border);
    border-radius: var(--radius-md); box-shadow: 0 10px 28px rgba(0,0,0,.12);
  }
  .mg-nav-panel a {
    display: block; padding: 10px 20px;
    font: 500 15px/1.3 var(--font-ui); color: var(--ink); text-decoration: none;
  }
  .mg-nav-panel a:hover { color: var(--green-deep); background: var(--cream); }
  .mg-nav-panel .sub-menu {
    position: static; display: block; border: 0; box-shadow: none;
    padding: 0 0 4px; margin: 0; background: transparent; min-width: 0;
  }
  .mg-nav-panel .sub-menu a { padding-left: 36px; font-size: 14px; color: var(--muted); }
}

/* --------------------------------------------------------------------------
   Editorial templates
   -------------------------------------------------------------------------- */

/* A page opens on its own H1, which carries its own space above it, so it sits
   tighter under the header than an article or an archive does. */
.mg-page { padding-block: 20px 72px; }
.mg-single, .mg-archive, .mg-404 { padding-block: 56px 72px; }
.mg-single h1 { margin-block: 10px 24px; }
.mg-teaser { padding-block: 28px; border-bottom: 1px solid var(--border); }
.mg-teaser:last-of-type { border-bottom: 0; }
.mg-teaser h2 { font-size: 30px; margin-block: 8px; }       /* §16 feature title */
.mg-teaser h2 a { color: var(--ink); text-decoration: none; }
.mg-teaser h2 a:hover { color: var(--green-deep); }
.mg-excerpt { color: var(--muted); }
.mg-404 { text-align: center; padding-block: 96px 120px; }
.mg-404 h1 { margin-block: 8px 16px; }

@media (max-width: 640px) {
  /* .mg-page keeps its 20px top here -- only the bottom comes in. */
  .mg-page { padding-block: 20px 48px; }
  .mg-single, .mg-archive { padding-block: 36px 48px; }
}

/* --------------------------------------------------------------------------
   Container gutters -- the width scale from the design spec.

     viewport   gutter/side   content
     >= 1440px      40px      1360px  (the max-width takes over here)
        1280px      32px      1216px
        1024px      24px       976px
         768px      20px       728px
        < 768px     16px      100% - 32px

   The containers themselves are §21's and are not touched: they already read
   --gutter and --dashboard-width, so redefining the token is enough. These are
   min-width queries and this file loads after §21, so they win over its
   max-width steps (24px at 900, 16px at 640) wherever the two overlap.

   At 1440 no rule is needed: calc(100% - 64px) is 1376, which max-width clamps
   to 1360, leaving exactly the 40px the spec asks for.
   -------------------------------------------------------------------------- */
:root { --gutter: 16px; }
@media (min-width: 768px)  { :root { --gutter: 20px; } }
@media (min-width: 1024px) { :root { --gutter: 24px; } }
@media (min-width: 1280px) { :root { --gutter: 32px; } }

/* On a dashboard page the header and footer follow the dashboard's width.
   .container is 1280 and .dashboard-container is 1360, so left as they were
   the wordmark sat 40px inside the left edge of the content beneath it --
   close enough to look like a mistake rather than a margin. Scoped to
   body.mg-dashboard, which mg_body_class() adds only to those pages, so
   editorial pages keep the 1280 measure they are set at. */
body.mg-dashboard .site-header .container,
body.mg-dashboard .site-footer .container {
  max-width: var(--dashboard-width);
}

/* --------------------------------------------------------------------------
   TEMPORARY -- nav hidden until the real menu exists.

   The only items are WordPress's Sample Page and a Dashboard link to the page
   you are already on. display:none takes it out of the accessibility tree as
   well, so a screen reader is not offered links nobody else can see.

   TO RESTORE: delete this block. The markup, the mobile disclosure and the
   menu registrations are all still in place.
   -------------------------------------------------------------------------- */
.mg-nav { display: none; }
