/* ============================================================
   Noosa Council Watch — "Minute Book"

   The visual language of council's own paperwork, turned around:
   form headers, a ruled margin, item numbers in a mono gutter,
   rubber-stamp decision marks, and redaction blocks. Official in
   register, adversarial in intent.

   Type
     Archivo          form headers and headlines, uppercase, tracked
     IBM Plex Serif   body — people read long editorial here
     IBM Plex Mono    every reference number, date, timestamp, tally

   Colour — lifted from council's own brand, then split by voice.
     Their palette, sampled from noosa.qld.gov.au's stylesheet:
       #627244 olive/moss (their primary), #55623c hover,
       #171717/#252722/#0a0b07 green-biased near-blacks,
       #d8d9d4 rule grey, #c40c06 alert red.

     olive  COUNCIL'S voice — structure, labels, rules, links. Using
            their own colour for the scaffolding makes the page read as
            official record rather than commentary about it.
     stamp  OUR voice — verdicts, stamps, redaction, alarm. The single
            bold spend, and deliberately the one colour that is not theirs.
     paper  bone carrying their green-grey bias, not a cool grey.

   Themes are three-state: bare :root is light; the media query is
   guarded so an explicit light choice beats a dark OS; the
   [data-theme="dark"] block lets the toggle win the other way. Dark
   steps are chosen against the dark ground, never inverted.
   ============================================================ */

/* ------------------------------------------------------------
   Self-hosted type. These used to come from fonts.googleapis.com,
   which handed Google the IP address of every reader - including
   readers of /contact/, a page that promises people they cannot be
   identified. Serving the files ourselves is the only way to keep
   that promise true.

   Archivo: OFL, Omnibus-Type. IBM Plex: OFL, IBM. See OFL.txt in
   this directory. Files are Google's own latin + latin-ext woff2
   subsets, unmodified; unicode-range means a browser only fetches
   the ones a page actually needs.
   ------------------------------------------------------------ */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/archivo-500-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: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/archivo-500-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: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/archivo-600-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: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/archivo-600-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: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/archivo-700-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: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/archivo-700-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: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/static/fonts/archivo-800-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: 'Archivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/static/fonts/archivo-800-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: 'IBM Plex Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-400-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: 'IBM Plex Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-400-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: 'IBM Plex Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-400-italic-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: 'IBM Plex Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-400-italic-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: 'IBM Plex Serif';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-600-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: 'IBM Plex Serif';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-serif-600-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-400-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-400-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-500-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-500-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-600-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: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-600-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;
}

:root {
  --paper:      #f2f2ec;
  --paper-2:    #e9e9e1;
  --ink:        #1a1c17;
  --ink-soft:   #5f665c;
  --ink-faint:  #8b9086;
  --rule:       #d8d9d4;   /* council's own rule grey */
  --rule-soft:  #e4e5df;
  --olive:      #627244;   /* council's primary */
  --olive-deep: #55623c;   /* council's hover */
  --stamp:      #b32014;
  --stamp-soft: #f4e3e0;
  --paper-0:    rgba(242, 242, 236, 0);   /* --paper at zero alpha */

  --chart-surface: #f7f7f1;
  --grid:          #e4e5df;
  --rain:          #3d8fd6;

  --display: "Archivo", ui-sans-serif, system-ui, "Segoe UI", Helvetica, Arial, sans-serif;
  --body:    "IBM Plex Serif", Georgia, "Times New Roman", serif;
  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --max:     64rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:      #191b16;
    --paper-2:    #20231d;
    --ink:        #e7e9e2;
    --ink-soft:   #9aa196;
    --ink-faint:  #6f766b;
    --rule:       #32362c;
    --rule-soft:  #282b23;
    --olive:      #9aac74;   /* their olive, lifted to hold the dark ground */
    --olive-deep: #b0c08c;
    --stamp:      #e0584a;
    --stamp-soft: #33201c;
    --paper-0:    rgba(25, 27, 22, 0);

    --chart-surface: #20231d;
    --grid:          #32362c;
    --rain:          #5fa8e8;
  }
}
:root[data-theme="dark"] {
  --paper: #191b16; --paper-2: #20231d; --ink: #e7e9e2;
  --ink-soft: #9aa196; --ink-faint: #6f766b;
  --rule: #32362c; --rule-soft: #282b23;
  --olive: #9aac74; --olive-deep: #b0c08c;
  --stamp: #e0584a; --stamp-soft: #33201c; --paper-0: rgba(25, 27, 22, 0);
  --chart-surface: #20231d; --grid: #32362c; --rain: #5fa8e8;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* This site is made of things that do not break where prose does: file
     numbers, application references, statute citations, transcript runs set in
     capitals. One of them ran a deputation page 18px past the right edge of a
     phone. break-word only acts when a word genuinely cannot fit, so ordinary
     lines are unaffected. */
  overflow-wrap: break-word;
}
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 1.5rem; }

a { color: var(--ink); text-decoration-color: var(--olive); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--stamp); }
:focus-visible { outline: 2px solid var(--stamp); outline-offset: 2px; }
.skip-link {
  position: fixed; left: 1rem; top: 1rem; z-index: 1000;
  padding: .55rem .85rem; background: var(--ink); color: var(--paper);
  font-family: var(--mono); font-size: .78rem; transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); color: var(--paper); }

/* ---------- masthead: a document header ---------- */
.masthead { border-bottom: 3px double var(--olive); background: var(--paper); }
.masthead .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1.5rem; padding-top: 2rem; padding-bottom: 1.05rem; }
.brand {
  font-family: var(--display); font-weight: 800; font-size: 1.12rem;
  text-transform: uppercase; letter-spacing: .16em; color: var(--ink); text-decoration: none;
}
.brand span { color: var(--olive); }
.brand-rule { flex: 1 1 2rem; height: 0; border-top: 2px solid var(--olive); min-width: 1rem; opacity: .55; }
/* One line, full width, under the brand row: who we are, for readers who
   arrived from a search onto a stranger's name. Hidden on the homepage. */
.masthead-tag {
  flex-basis: 100%; margin: .1rem 0 0; font-family: var(--body); font-size: .9rem;
  color: var(--ink-soft); line-height: 1.45;
}
.masthead-tag a { color: var(--olive-deep); white-space: nowrap; }
/* Item gap has to beat the word gap inside "Behind closed doors", or the nav
   reads as one run of words. The hover rule then underlines a whole item, so
   what you are about to click is unambiguous. */
.masthead nav { display: flex; flex-wrap: wrap; gap: 1.1rem 1.9rem; }
.masthead nav a {
  font-family: var(--mono); font-size: .76rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-soft); text-decoration: none;
  padding-bottom: .22rem; border-bottom: 2px solid transparent;
}
.masthead nav a:hover,
.masthead nav a:focus-visible {
  color: var(--olive-deep); border-bottom-color: var(--olive);
}

/* main carries .wrap for its width, and a bare `main` loses to `.wrap` on
   specificity - which silently zeroed this padding and left every h1 sitting
   flush against the masthead rule. Match the class so it applies. */
main.wrap { padding: clamp(2.5rem, 4.5vw, 3.5rem) 1.5rem 4rem; }

/* ---------- headings: form headers ---------- */
h1 {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(1.85rem, 4.2vw, 2.7rem); line-height: 1.08;
  letter-spacing: -0.02em; text-wrap: balance;
  margin: 0 0 .85rem;
}
h2 {
  font-family: var(--display); font-weight: 700; font-size: 1.02rem;
  text-transform: uppercase; letter-spacing: .1em;
  margin: 3rem 0 .9rem; padding-top: .6rem; border-top: 2px solid var(--olive);
}
h3 { font-family: var(--display); font-weight: 700; font-size: .92rem; text-transform: uppercase; letter-spacing: .08em; margin: 2rem 0 .5rem; color: var(--olive-deep); }

.lede { font-size: 1.16rem; line-height: 1.55; color: var(--ink); max-width: 44rem; margin: 0 0 1rem; }
.hero { padding-bottom: 1.5rem; margin-bottom: 2rem; border-bottom: 2px solid var(--olive); }
.hero-sub { max-width: 44rem; color: var(--ink-soft); }
p { max-width: 44rem; }

.meta, .crumb { font-family: var(--mono); font-size: .76rem; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .06em; }
.crumb { margin: 0 0 .75rem; }
.snip { color: var(--ink-soft); font-size: .95rem; margin: .25rem 0 0; }
.empty { color: var(--ink-soft); font-style: italic; }

.note {
  font-family: var(--body); font-size: .93rem; color: var(--ink-soft);
  background: var(--paper-2); border-left: 3px solid var(--olive);
  padding: .75rem 1rem; border-radius: 0;
}
.note.callout { border-left-color: var(--stamp); background: var(--stamp-soft); color: var(--ink); }
.note.callout p { margin: 0; }

/* ---------- counters: register tallies ---------- */
.counters { display: grid; grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr)); gap: 0; margin: 0 0 2rem; border: 1px solid var(--olive); border-top: 3px solid var(--olive); }
.counter { padding: .9rem 1rem; border-right: 1px solid var(--olive); }
.counter:last-child { border-right: 0; }
.counter b {
  display: block; color: var(--olive-deep); font-family: var(--display); font-weight: 800;
  font-size: 1.9rem; line-height: 1.05; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.counter b small { font-family: var(--display); font-size: .85rem; font-weight: 600; margin-left: .1rem; }
.counter span { display: block; font-family: var(--mono); font-size: .68rem; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-soft); margin-top: .35rem; }
.counter.alarm { background: var(--stamp-soft); }
.counter.alarm b { color: var(--stamp); }

/* ---------- the homepage: this week, latest, everything ---------- */
/* The next meeting, as a thing to do rather than a date. */
.thisweek { border: 1px solid var(--olive); border-top: 3px solid var(--olive); padding: 1rem 1.25rem 1.1rem; margin: 0 0 2rem; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .5rem 2rem; align-items: center; }
.thisweek h2 { margin: 0 0 .25rem; }
.thisweek p { margin: 0; }
.thisweek p.then { margin-top: .4rem; font-size: .9rem; color: var(--ink-soft); }
.thisweek .actions { display: flex; flex-wrap: wrap; gap: .6rem; }
@media (max-width: 44rem) { .thisweek { grid-template-columns: minmax(0, 1fr); } }

/* Latest: one dated list across every register (latest.py). */
ol.latest { list-style: none; margin: 0; padding: 0; }
ol.latest > li { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: .4rem 1.2rem; padding: .85rem 0; border-bottom: 1px solid var(--rule-soft); }
ol.latest .when { font-family: var(--mono); font-size: .76rem; text-transform: uppercase; letter-spacing: .05em; color: var(--olive-deep); padding-top: .25rem; }
ol.latest .what { margin: 0; overflow-wrap: anywhere; }
ol.latest .what p { margin: 0 0 .25rem; }
ol.latest .what p:last-child { margin-bottom: 0; }
ol.latest .snip { font-size: .92rem; color: var(--ink-soft); }
ol.latest .added { font-family: var(--mono); font-size: .7rem; color: var(--ink-faint); white-space: nowrap; }
.reg { display: inline-block; font-family: var(--mono); font-size: .66rem; text-transform: uppercase; letter-spacing: .08em; color: var(--olive-deep); border: 1px solid var(--olive); padding: .05rem .4rem; margin-right: .45rem; vertical-align: 2px; white-space: nowrap; }
.reg.ours { color: var(--stamp); border-color: var(--stamp); }
@media (max-width: 44rem) { ol.latest > li { grid-template-columns: minmax(0, 1fr); gap: .15rem; } }

/* Every register in the band's groups, with the figure each leads with. */
.regindex { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.2rem 2rem; margin: 0 0 1rem; }
.regindex h3 { margin: 0 0 .35rem; padding-bottom: .3rem; border-bottom: 1px solid var(--rule); }
.regindex ul { list-style: none; margin: 0; padding: 0; }
.regindex li { display: flex; justify-content: space-between; gap: .6rem; padding: .3rem 0; border-bottom: 1px solid var(--rule-soft); font-size: .95rem; }
.regindex li a { text-decoration: none; border-bottom: 1px solid var(--rule); }
.regindex li a:hover { border-bottom-color: var(--stamp); }
.regindex li b { font-family: var(--mono); font-weight: 500; font-size: .8rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
@media (max-width: 52rem) { .regindex { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 30rem) { .regindex { grid-template-columns: minmax(0, 1fr); } }

/* The counters, moved to the foot of the homepage: plainer there. */
.counters.quiet { border-top-width: 1px; margin-top: .5rem; }

/* ---------- the stamp ---------- */
.stamp {
  display: inline-block; float: right; margin: .2rem 0 .75rem 1.25rem;
  font-family: var(--display); font-weight: 800; text-transform: uppercase;
  letter-spacing: .1em; color: var(--stamp);
  border: 2px solid var(--stamp); border-radius: 3px;
  padding: .45rem .9rem; text-align: center; line-height: 1.15;
  transform: rotate(-2.2deg); opacity: .92;
  box-shadow: inset 0 0 0 1px var(--paper);
}
.stamp .verdict-word { display: block; font-size: 1.05rem; }
.stamp .tally { display: block; font-family: var(--mono); font-size: .82rem; font-weight: 600; letter-spacing: .04em; }

.panel { border-top: 2px solid var(--olive); padding-top: 1.25rem; margin-top: 2.5rem; }
.panel h2 { margin-top: 0; border-top: 0; padding-top: 0; color: var(--olive-deep); }
.verdict { font-family: var(--body); font-size: 1.1rem; line-height: 1.5; border-left: 3px solid var(--stamp); padding-left: 1rem; margin: .9rem 0; }
.btn {
  display: inline-block; font-family: var(--mono); font-size: .78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  background: var(--olive); color: #fff; padding: .6rem 1.1rem; text-decoration: none;
}
.btn:hover { background: var(--stamp); color: var(--paper); }

/* ---------- lists ---------- */
ul.meeting-list, ul.issue-list, ul.sources { list-style: none; padding: 0; margin: 0; }
/* A development application's files, by title: council's filenames run long and unbroken. */
ul.doc-list { margin: 0 0 1.2rem; padding-left: 1.2rem; }
ul.doc-list li { overflow-wrap: anywhere; padding: .15rem 0; }
ul.meeting-list li, ul.issue-list li { padding: .7rem 0; border-bottom: 1px solid var(--rule-soft); }
ul.issue-list a { font-family: var(--display); font-weight: 700; font-size: .98rem; text-transform: uppercase; letter-spacing: .04em; text-decoration: none; border-bottom: 2px solid var(--olive); }
ul.sources li { padding: .35rem 0; font-size: .95rem; }

/* ---------- tables: the register ---------- */
table.grid { width: 100%; border-collapse: collapse; margin: 1.25rem 0; font-size: .93rem; }
table.grid th {
  text-align: left; font-family: var(--mono); font-size: .68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-soft);
  border-bottom: 2px solid var(--olive); padding: .5rem .65rem;
}
table.grid td { padding: .5rem .65rem; border-bottom: 1px solid var(--rule-soft); vertical-align: top; }
table.grid td.date { font-family: var(--mono); font-size: .8rem; color: var(--ink-soft); white-space: nowrap; }
table.grid .num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; width: 5.5rem; }
table.grid tr.covered td { background: var(--stamp-soft); }
table.grid tbody tr:hover td { background: var(--paper-2); }
.dot { color: var(--stamp); font-weight: 900; margin-right: .4rem; }
td.num.warm { color: var(--stamp); font-weight: 600; }
td.num.zero { color: var(--stamp); }
/* A year-per-column table (pay and expenses): twelve narrow figure columns
   and a name. Nothing in it benefits from wrapping - "2014-15" broke into two
   lines under the 5.5rem .num width, and names split in half - so every cell
   holds its line and the wrapper scrolls sideways where the screen is narrow. */
table.grid.years { font-size: .86rem; }
table.grid.years th, table.grid.years td { white-space: nowrap; padding-left: .3rem; padding-right: .3rem; }
table.grid.years th { font-size: .62rem; letter-spacing: .04em; }
table.grid.years .num { width: auto; }
table.grid.years th.num { text-align: right; }
a.tiny { font-family: var(--mono); font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); }

/* ---------- redaction bars ----------
   A real bar chart whose bars are drawn as blacked-out blocks: width is
   proportional to the count, so the rhetoric never distorts the data. */
td.bar { width: 55%; }
td.bar span {
  display: block; height: .85rem; min-width: 3px;
  background-color: var(--ink);
  background-image: repeating-linear-gradient(90deg, transparent 0 13px, var(--paper) 13px 16px);
}
tr:hover td.bar span { background-color: var(--stamp); }

/* ---------- agenda: mono gutter, ruled ---------- */
ol.agenda { list-style: none; padding: 0; margin: 1.25rem 0; border-top: 2px solid var(--olive); }
ol.agenda li { padding: .5rem 0; border-bottom: 1px solid var(--rule-soft); }
ol.agenda li.procedural { opacity: .5; font-size: .9rem; }
/* Pre-2023 decisions: the summary row is the agenda row; it opens to the motion. */
ol.agenda li.decision details > summary { cursor: pointer; list-style: none; }
ol.agenda li.decision details > summary::-webkit-details-marker { display: none; }
ol.agenda li.decision details > summary .iname::after { content: " \25B8"; color: var(--ink-faint); font-size: .8em; }
ol.agenda li.decision details[open] > summary .iname::after { content: " \25BE"; }
ol.agenda li.decision .dbody { margin: .5rem 0 .25rem 4.9rem; font-size: .95rem; overflow-wrap: anywhere; }
ol.agenda li.decision .dbody .motion { white-space: pre-line; }
ol.agenda li.decision:target { background: var(--rule-soft); }
@media (max-width: 34rem) { ol.agenda li.decision .dbody { margin-left: 0; } }
ol.agenda .row { display: flex; gap: .9rem; align-items: baseline; }
ol.agenda .outline { font-family: var(--mono); font-size: .78rem; font-weight: 500; color: var(--ink-faint); min-width: 4rem; flex-shrink: 0; text-align: right; }
ol.agenda .iname { flex: 1; }
ol.agenda .ts {
  font-family: var(--mono); font-size: .76rem; font-weight: 600;
  border: 1px solid var(--olive); color: var(--olive-deep);
  padding: .12rem .5rem; text-decoration: none; white-space: nowrap;
}
ol.agenda .ts::before { content: "\25B8 "; color: var(--stamp); }
ol.agenda .ts:hover { background: var(--stamp); border-color: var(--stamp); color: var(--paper); }
ol.agenda .ts:hover::before { color: var(--paper); }
li.depth-1 { padding-left: 1.1rem; } li.depth-2 { padding-left: 2.2rem; } li.depth-3 { padding-left: 3.3rem; }
.docs { margin: .4rem 0 0 4.9rem; display: flex; flex-wrap: wrap; gap: .4rem; align-items: baseline; }
.doc { font-family: var(--mono); font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; padding: .1rem .45rem; border: 1px solid var(--rule); color: var(--ink-faint); }
.doc.report { border-color: var(--olive); color: var(--olive-deep); }
/* Document names are links into council's own viewer, one file each. They keep
   the pill shape rather than looking like body-copy links. */
a.doc { text-decoration: none; }
a.doc:hover, a.doc:focus-visible { background: var(--olive); border-color: var(--olive); color: var(--paper); }

/* ---------- editorial: ruled margin, like a minute book ---------- */
.editorial { border-left: 3px solid var(--olive); padding: .25rem 0 .25rem 1.5rem; margin: 1.75rem 0; }
.editorial.bare { border-left: 0; padding-left: 0; }
.editorial .label, .related .label {
  font-family: var(--mono); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .12em; color: var(--olive-deep); font-weight: 600; margin: 0 0 .6rem;
}
.editorial h2 { font-size: .92rem; margin: 1.75rem 0 .5rem; border-top: 0; padding-top: 0; color: var(--olive-deep); }
.editorial blockquote {
  border-left: 3px solid var(--stamp); margin: 1.1rem 0; padding: .3rem 0 .3rem 1.1rem;
  color: var(--ink-soft); font-style: italic;
}
.related { border: 1px solid var(--rule); padding: .9rem 1.2rem; margin: 1.75rem 0; }
.related ul { margin: 0; padding-left: 1.1rem; }

/* ---------- charts ---------- */
figure.chart { margin: 1.75rem 0; background: var(--chart-surface); border: 1px solid var(--olive); padding: 1rem .75rem .5rem; overflow-x: auto; }
figure.chart svg { display: block; width: 100%; min-width: 34rem; height: auto; }
figure.chart figcaption { font-family: var(--mono); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); padding: .6rem .5rem 0; line-height: 1.5; }
.chart .grid { stroke: var(--grid); stroke-width: 1; }
.chart .axis { stroke: var(--ink-soft); stroke-width: 1; opacity: .5; }
.chart text.ax { fill: var(--ink-soft); font-size: 10px; font-family: var(--mono); }
/* Series colour comes from --c (light) / --cd (dark), set inline on each mark.
   These must be read DIRECTLY on the element: a `--series: var(--c)` shortcut
   declared on :root resolves --c against :root, where it does not exist, so the
   property is invalid at computed-value time and inherits as invalid. For
   `stroke` that silently falls back to the initial value `none` - i.e. lines
   that exist in the markup and never draw. Hence the repetition below. */
.chart rect.rain { fill: var(--c, var(--rain)); }
.chart rect.rain:hover { fill: var(--stamp); }
.chart line.mean { stroke: var(--ink); stroke-width: 2; stroke-dasharray: 5 4; opacity: .6; }
.chart text.mean-lbl { fill: var(--ink-soft); font-size: 10px; font-family: var(--mono); text-transform: uppercase; }
.chart path.ln { fill: none; stroke: var(--c); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart circle.dot { fill: var(--c); stroke: var(--chart-surface); stroke-width: 2; opacity: 0; }
.chart circle.dot:hover { opacity: 1; }
.chart text.ser-lbl { fill: var(--c); font-size: 10px; font-weight: 700; font-family: var(--mono); text-transform: uppercase; }

/* ---------- footer: the colophon ---------- */
.foot { border-top: 3px double var(--olive); background: var(--paper); padding: 2.25rem 0 3rem; margin-top: 3.5rem; font-size: .88rem; color: var(--ink-soft); }
.foot p { max-width: 48rem; margin: 0 0 .7rem; }
.foot .meta { font-family: var(--mono); font-size: .7rem; }

/* ---------- the page frame: breadcrumb + register strapline ----------
   One style on every page below the homepage, rendered by base.html. */
nav.crumbs { font-family: var(--mono); font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); margin: 0 0 .3rem; }
nav.crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .3rem .5rem; }
nav.crumbs li + li::before { content: "\203A"; margin-right: .5rem; color: var(--ink-faint); }
nav.crumbs a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--rule); }
nav.crumbs a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
nav.crumbs [aria-current] { color: var(--ink); }
.strap { font-family: var(--body); font-size: .92rem; color: var(--ink-soft); margin: 0 0 1.4rem; max-width: 46rem; border-left: 3px solid var(--olive); padding-left: .8rem; }
.strap a { color: var(--ink-soft); }

/* ---------- section tabs: a register's own pages, one row ---------- */
nav.tabs { border-bottom: 1px solid var(--rule); margin: 0 0 1.75rem; }
nav.tabs ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0 1.6rem; }
nav.tabs a { display: inline-block; padding: .55rem 0 .5rem; font-family: var(--display); font-weight: 600; font-size: .8rem; text-transform: uppercase; letter-spacing: .07em; text-decoration: none; color: var(--ink-soft); border-bottom: 3px solid transparent; margin-bottom: -1px; }
nav.tabs a:hover { color: var(--stamp); }
nav.tabs a[aria-current] { color: var(--ink); border-bottom-color: var(--olive); }
nav.tabs a small { font-family: var(--mono); font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--ink-faint); margin-left: .35rem; }

/* ---------- a passage of the recording, cued to the second ----------
   Speaker pages ("Lately"). */
.chamber { border: 1px solid var(--rule); border-left: 4px solid var(--olive); padding: 1rem 1.25rem 1rem 1.4rem; margin: 0 0 2rem; }
.chamber .label { font-family: var(--display); font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--olive-deep); margin: 0 0 .5rem; }
.chamber .label a { color: var(--olive-deep); text-decoration: none; border-bottom: 1px solid var(--olive); }
.chamber blockquote { margin: 0 0 .75rem; padding: 0; }
.chamber blockquote:last-of-type { margin-bottom: .4rem; }
.chamber .who { display: block; font-family: var(--mono); font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); margin-bottom: .15rem; }
.chamber .who a { color: var(--olive-deep); text-decoration: none; border-bottom: 1px solid var(--olive); margin-right: .5rem; }
.chamber .who a::before { content: "\25B6\00a0"; font-size: .7em; }
.chamber blockquote p { margin: 0; }
.chamber .hint { font-size: .82rem; color: var(--ink-soft); margin: 0; }
.chamber.wide { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem 2rem; }
.chamber.wide .label, .chamber.wide .hint { grid-column: 1 / -1; }
@media (max-width: 44rem) { .chamber.wide { grid-template-columns: 1fr; } }

/* ---------- elsewhere on this site: every page that links here ----------
   Written into the foot of <main> by elsewhere.py after the build. */
.elsewhere { border: 1px solid var(--rule); border-top: 3px solid var(--olive); padding: 1rem 1.25rem 1.2rem; margin: 2.25rem 0 0; }
.elsewhere .label { font-family: var(--display); font-weight: 700; font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--olive-deep); margin: 0 0 .2rem; }
.elsewhere > p { margin: 0 0 .9rem; font-size: .92rem; color: var(--ink-soft); }
.elsewhere .cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem 2rem; }
.elsewhere h3 { margin: 0 0 .3rem; font-size: .74rem; }
.elsewhere ul { list-style: none; margin: 0; padding: 0; }
.elsewhere li { padding: .25rem 0; border-bottom: 1px solid var(--rule-soft); font-size: .93rem; }
.elsewhere li .meta { display: block; margin: 0; font-size: .68rem; }
@media (max-width: 44rem) { .elsewhere .cols { grid-template-columns: 1fr; } }

/* ---------- the fat footer: every register, from every page ---------- */
.foot-map { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 1.2rem 1.6rem; margin: 0 0 2rem; padding-bottom: 1.6rem; border-bottom: 1px solid var(--rule); }
.foot-map h2 { font-size: .72rem; margin: 0 0 .4rem; color: var(--olive-deep); }
.foot-map ul { list-style: none; margin: 0; padding: 0; }
.foot-map li { padding: .18rem 0; font-size: .86rem; }
.foot-map a { text-decoration: none; color: var(--ink); border-bottom: 1px solid var(--rule); }
.foot-map a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
@media (max-width: 52rem) { .foot-map { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 30rem) { .foot-map { grid-template-columns: 1fr; } }

/* Full-width tables on desktop. `display: block` is what makes a table
   horizontally scrollable, but it also stops `width: 100%` applying, so it is
   scoped to narrow viewports where the scroll is actually needed. */
table.grid { display: table; width: 100%; }
@media (max-width: 44rem) {
  table.grid { display: block; overflow-x: auto; }
  /* Only what would be wrong to break stays on one line. Setting nowrap on the
     whole table made the court register 1,868px wide on a 375px phone: every
     matter title held on one line, and Outcome and Before pushed so far off the
     right edge that nothing on screen said they were there. Wrapping the prose
     columns brings the same table back to about a screen and a half. */
  table.grid td, table.grid th, table.grid td.date { white-space: normal; }
  table.grid .num, table.grid .closed, table.grid .pill { white-space: nowrap; }
  /* The date column is held on one line by giving it room for a date rather
     than by forbidding the break. Council files some multi-year grants under a
     period of "MEC Multi-year Environment Collaborative Grant - ROUND 1 year
     1", and nowrap made that 61-character string set the width of the column:
     525px for a cell reading "2019-20", the other four columns crushed into
     what was left, and rows nine lines deep on a recipient's page. A real date
     fits the floor and never wraps; anything that is not a date now wraps
     instead of deciding the table. */
  table.grid th:first-child, table.grid td:first-child { min-width: 6.5rem; }
  table.grid.legal th:nth-child(2), table.grid.legal td:nth-child(2) { min-width: 11rem; }

  /* Five columns of prose do not survive a 375px screen as a table. On a
     recipient's page the project description got 109px -- ten lines of two
     words -- while Amount and the source link sat off the right edge, and every
     row was nine lines deep. `.stack` gives up the grid and prints each row as
     the record it is: the year and who it went to, then the project, then the
     money and the document it came from.

     The heading row is dropped because each value says what it is -- a year, a
     name, a dollar amount -- and a column heading in a stack has nothing to sit
     above. The elements carry explicit ARIA roles in the template, because
     changing an element's display takes its implicit table role with it. */
  table.grid.stack, table.grid.stack tbody { display: block; }
  table.grid.stack thead { display: none; }
  table.grid.stack tr {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: .15rem .55rem;
    padding: .75rem 0; border-bottom: 1px solid var(--rule-soft);
  }
  table.grid.stack td { display: block; border: 0; padding: 0; }
  /* The prose columns take a line of their own; the short ones share the first. */
  table.grid.stack td.quiet { order: 1; flex-basis: 100%; font-size: .95rem; }
  table.grid.stack td.num { margin-left: auto; text-align: right; font-weight: 600; }
  table.grid.stack td:empty { display: none; }
  table.grid.stack tbody tr:hover td { background: none; }

  /* A table in a dossier is written in Markdown and carries no class of ours,
     so it got no scroll box and pushed the whole page sideways instead -- the
     eight-column vote table on the Lions Park page made every line of prose on
     it start off-screen. */
  .editorial table { display: block; overflow-x: auto; max-width: 100%; }

  /* Say that a table continues past the edge. The two `local` layers are the
     paper itself and travel with the content, so each covers its shadow when
     that end is reached: the shadow is visible only while there is more table
     to see, and a table that fits shows nothing at all. */
  table.grid, .editorial table {
    background:
      linear-gradient(to right, var(--paper) 30%, var(--paper-0)) left / 2rem 100% no-repeat local,
      linear-gradient(to left,  var(--paper) 30%, var(--paper-0)) right / 2rem 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.15), var(--paper-0)) left / .7rem 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.15), var(--paper-0)) right / .7rem 100% no-repeat scroll;
  }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }
@media (max-width: 34rem) {
  .masthead .wrap { gap: .5rem 1rem; padding-top: 1.35rem; padding-bottom: .8rem; }
  .brand-rule { display: none; }
  ol.agenda .outline { min-width: 3rem; }
  .docs { margin-left: 0; }
  .stamp { float: none; display: block; margin: 1rem 0; transform: rotate(-1.2deg); max-width: 11rem; }
}

/* chart legend keys — identity never rests on colour alone: each swatch is
   paired with the gauge's name and its span */
figure.chart figcaption .key { display: inline-flex; align-items: center; gap: .35rem; margin-right: 1rem; text-transform: none; letter-spacing: 0; }
figure.chart figcaption .sw { display: inline-block; width: .7rem; height: .7rem; background: var(--c); border-radius: 2px; flex-shrink: 0; }

/* Dark theme: same marks, the palette's separately-chosen dark steps. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart path.ln { stroke: var(--cd); }
  :root:not([data-theme="light"]) .chart circle.dot { fill: var(--cd); }
  :root:not([data-theme="light"]) .chart text.ser-lbl { fill: var(--cd); }
  :root:not([data-theme="light"]) .chart rect.rain { fill: var(--cd, var(--rain)); }
  :root:not([data-theme="light"]) figure.chart figcaption .sw { background: var(--cd); }
}
:root[data-theme="dark"] .chart path.ln { stroke: var(--cd); }
:root[data-theme="dark"] .chart circle.dot { fill: var(--cd); }
:root[data-theme="dark"] .chart text.ser-lbl { fill: var(--cd); }
:root[data-theme="dark"] .chart rect.rain { fill: var(--cd, var(--rain)); }
:root[data-theme="dark"] figure.chart figcaption .sw { background: var(--cd); }

/* ---------- court register ---------- */
/* Outcome marks. Won/lost are OUR reading of a judgment, so they carry the
   stamp red and the olive; the rest stay neutral so a settlement does not
   read as a verdict. */
.pill {
  display: inline-block; font-family: var(--mono); font-size: .66rem;
  text-transform: uppercase; letter-spacing: .08em; font-weight: 600;
  padding: .18rem .45rem; border: 1px solid var(--rule); color: var(--ink-soft);
  white-space: nowrap;
}
.pill.won    { border-color: var(--olive); color: var(--olive-deep); }
.pill.lost   { border-color: var(--stamp); color: var(--stamp); background: var(--stamp-soft); }
.pill.live   { border-color: var(--stamp); color: var(--stamp); }
.pill.settled{ border-color: var(--ink-faint); color: var(--ink-soft); }
.pill.unknown{ border-style: dashed; color: var(--ink-faint); }

table.grid.legal td { font-size: .9rem; }
table.grid.legal th:nth-child(3), table.grid.legal td:nth-child(3) { width: 8rem; }
table.grid.legal td strong { font-weight: 600; }
table.grid.legal .sub {
  display: block; font-size: .82rem; color: var(--ink-soft); margin-top: .15rem;
}
table.grid.legal .closed {
  font-size: .72rem; color: var(--stamp); white-space: nowrap;
}

ul.case-list { list-style: none; padding: 0; margin: 1.25rem 0; border-top: 2px solid var(--olive); }
ul.case-list li { padding: .85rem 0; border-bottom: 1px solid var(--rule-soft); }
ul.case-list .case-head { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
ul.case-list .ref {
  font-family: var(--mono); font-size: .78rem; color: var(--ink-faint);
}
ul.case-list p { margin: .35rem 0 0; }
/* Register notes run long; the mono/uppercase .meta treatment is for stamps
   and dates, not for a sentence. */
.case-note { font-size: .86rem; color: var(--ink-soft); }
.pill.flat { border-color: var(--ink-faint); color: var(--ink); }
/* Report-backs: a return after the date council set. */
a.late { color: var(--stamp); }
td.back { min-width: 11rem; }
@media (min-width: 720px) {
  table.rb { table-layout: fixed; }
  table.rb th:first-child { width: 10.5rem; }
  table.rb th:last-child { width: 15rem; }
}

/* Contact form. No JS; native POST to /contact/submit. Honeypot hidden off-screen. */
form.contact { margin: 1.5rem 0 2rem; max-width: 40rem; }
form.contact label {
  display: block; margin: 1.1rem 0 .35rem; font-weight: 600;
  font-family: var(--mono); font-size: .8rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--ink);
}
form.contact label .opt {
  font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--ink-faint);
}
form.contact textarea,
form.contact input[type=text],
form.contact input[type=email] {
  width: 100%; box-sizing: border-box; padding: .7rem .75rem;
  font-family: var(--body); font-size: 1rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--ink-faint); border-radius: 2px;
}
form.contact input[type=email] { max-width: 26rem; }
form.contact textarea:focus,
form.contact input[type=text]:focus,
form.contact input[type=email]:focus {
  outline: 2px solid var(--olive); outline-offset: 1px; border-color: var(--olive);
}
form.contact .meta { margin: .4rem 0 0; text-transform: none; letter-spacing: 0; }
form.contact button {
  margin-top: 1.25rem; padding: .55rem 1.4rem; cursor: pointer;
  font-family: var(--mono); font-size: .85rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
  color: #fff; background: var(--olive); border: none; border-radius: 2px;
}
form.contact button:hover { background: var(--ink); }
/* Honeypot: kept in the DOM for bots, removed from view and a11y tree. */
form.contact .hp {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

/* ---------- search (served by the /search/ service, styled here) ----------
   The search page is rendered by a separate Flask app, but it links THIS
   stylesheet and uses the same masthead and footer markup as every other
   page. Its styles live here so there is one theme, not two that drift. */
form.search { display: flex; gap: .5rem; flex-wrap: wrap; margin: 0 0 .9rem; max-width: 52rem; }
form.search input[type=search] {
  flex: 1 1 22rem; font-family: var(--mono); font-size: .95rem;
  padding: .7rem .75rem; color: var(--ink); background: var(--paper);
  border: 1px solid var(--ink-faint); border-radius: 2px;
}
form.search input[type=search]:focus,
form.search input[type=date]:focus {
  outline: 2px solid var(--olive); outline-offset: 1px; border-color: var(--olive);
}
form.search button {
  padding: .55rem 1.4rem; cursor: pointer;
  font-family: var(--mono); font-size: .85rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .05em;
  color: #fff; background: var(--olive); border: none; border-radius: 2px;
}
form.search button:hover { background: var(--ink); }
.search-filters { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.search-filters label {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-faint);
}
.search-filters input[type=date] {
  font-family: var(--mono); font-size: .82rem; padding: .45rem .5rem;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--rule); border-radius: 2px;
}

/* Collection filters. Same pill vocabulary as .doc elsewhere on the site. */
ul.facets { display: flex; gap: .4rem; flex-wrap: wrap; margin: 1.2rem 0 1.4rem; padding: 0; list-style: none; }
ul.facets a {
  display: inline-block; font-family: var(--mono); font-size: .72rem;
  text-transform: uppercase; letter-spacing: .05em; text-decoration: none;
  padding: .28rem .65rem; border: 1px solid var(--rule); border-radius: 2px;
  color: var(--ink-soft); background: var(--paper-2);
}
ul.facets a:hover { border-color: var(--olive); color: var(--olive-deep); }
ul.facets a[aria-current] { background: var(--olive); color: #fff; border-color: var(--olive); }

.result { padding: 1.15rem 0; border-top: 1px solid var(--rule-soft); }
.result h2 {
  font-family: var(--display); font-weight: 700; font-size: 1.02rem;
  text-transform: none; letter-spacing: -0.01em; line-height: 1.35;
  margin: 0 0 .3rem; padding-top: 0; border-top: none;
}
.result h2 a { text-decoration: none; color: var(--ink); }
.result h2 a:hover { color: var(--olive-deep); text-decoration: underline; }
.result .snip { margin: 0 0 .5rem; color: var(--ink-soft); font-size: .95rem; max-width: 52rem; }
.result .snip mark {
  background: var(--stamp-soft); color: var(--ink);
  padding: 0 .12em; font-weight: 600; border-radius: 1px;
}
.result .link { font-family: var(--mono); font-size: .78rem; margin: 0; }
.result .link a { text-decoration: none; border-bottom: 1px solid var(--olive); }
.result .gone { font-family: var(--mono); font-size: .78rem; color: var(--stamp); margin: 0; }
.result .hint {
  font-family: var(--mono); font-size: .7rem; color: var(--ink-faint);
  text-transform: uppercase; letter-spacing: .05em;
}
.count { font-family: var(--mono); font-size: .82rem; color: var(--ink-soft); margin: 0 0 .4rem; }
.pager { display: flex; gap: .6rem; align-items: center; margin: 1.8rem 0; font-family: var(--mono); font-size: .8rem; }
.pager a { padding: .4rem .8rem; border: 1px solid var(--rule); border-radius: 2px; text-decoration: none; background: var(--paper-2); }
.pager a:hover { border-color: var(--olive); }
table.corpus { width: 100%; border-collapse: collapse; margin: 1rem 0 2rem; font-size: .95rem; max-width: 44rem; }
table.corpus th, table.corpus td { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--rule-soft); }
table.corpus th {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-faint);
}
table.corpus td.n, table.corpus th.n { font-family: var(--mono); text-align: right; }

/* ---------- deputations register ---------- */
.subnav { border-bottom: 1px solid var(--rule); background: var(--paper-2); }
.subnav .wrap { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.4rem; padding-block: .6rem; }
.subnav-label {
  font-family: var(--mono); font-size: .68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .12em; color: var(--ink-faint);
}
/* Four columns, one per group: a ruled heading, its links beneath. A heading
   set in the same mono caps as the links read as one more link; smaller,
   fainter, wider-tracked and ruled off, it reads as a heading. Columns drop
   to two, then one, as the viewport narrows; the phone block below replaces
   the strip block below replaces all of this under 52rem. */
.subnav .wrap { padding-block: .65rem .75rem; }
.subnav nav { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .8rem 2rem; width: 100%; }
/* align-content matters: a stretched grid cell would space a three-line
   group's lines apart and put its links lower than its neighbours'. */
.subnav .group { display: flex; flex-wrap: wrap; align-items: baseline; align-content: flex-start; gap: .35rem 1.1rem; }
.subnav .group-label {
  flex-basis: 100%; font-family: var(--mono); font-size: .6rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .16em; color: var(--ink-faint);
  padding-bottom: .3rem; border-bottom: 1px solid var(--rule); margin-bottom: .1rem;
}
.subnav nav a {
  font-family: var(--mono); font-size: .74rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); text-decoration: none;
  padding-bottom: .15rem; border-bottom: 2px solid transparent;
}
.subnav nav a:hover { color: var(--olive-deep); border-bottom-color: var(--olive); }
.subnav nav a[aria-current] { color: var(--ink); border-bottom-color: var(--olive); }

ol.deps { list-style: none; padding: 0; margin: 1.2rem 0 0; }
ol.deps li { padding: 1rem 0; border-top: 1px solid var(--rule-soft); }
ol.deps .meta { display: flex; flex-wrap: wrap; gap: .5rem .8rem; align-items: baseline; margin: 0 0 .3rem; }
ol.deps .meta a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--rule); }
ol.deps .meta a:hover { color: var(--olive-deep); border-bottom-color: var(--olive); }
ol.deps .who { font-family: var(--display); font-weight: 700; font-size: 1rem; margin: 0 0 .25rem; }
ol.deps .who .topic { font-weight: 400; color: var(--ink-soft); }
ol.deps .snip { margin: 0; color: var(--ink-soft); font-size: .93rem; }
ol.deps.compact li { padding: .7rem 0; }
ol.deps.compact .meta { margin: 0 0 .15rem; }

/* Document series index. Same shape as ol.deps -- a stack of rules with a
   strong title and a quiet meta line -- but each row is a series rather than
   a person, and the count is the thing being scanned for. */
ul.doc-series { list-style: none; padding: 0; margin: 1.2rem 0 0; }
ul.doc-series li { padding: .85rem 0; border-top: 1px solid var(--rule-soft); }
ul.doc-series .who { font-family: var(--display); font-weight: 700; font-size: 1.05rem; margin: 0 0 .25rem; }
ul.doc-series .meta { display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: baseline; margin: 0; }
ul.doc-series .replaced { color: var(--stamp); }
ul.doc-series .replaced strong { font-variant-numeric: tabular-nums; }

/* Secondary detail inside a table cell — project descriptions, the program a
   grant came from. Present, but not competing with the name and the figure. */
.quiet { color: var(--ink-soft); }
td.quiet { font-size: .88rem; }

/* The "why this is hard" list: each item is a claim with evidence, so it gets
   room to breathe rather than being compressed into a bullet run. */
ul.reasons li { padding: .6rem 0; }
ul.reasons strong { font-family: var(--display); }
ul.reasons code { font-family: var(--mono); font-size: .85em; }

/* Unadorned list, for the few places a bullet adds nothing. */
ul.plain { list-style: none; padding: 0; margin: 1rem 0; }
ul.plain li { padding: .45rem 0; border-top: 1px solid var(--rule-soft); }

/* A document council has revised in place: the copy we hold no longer exists
   anywhere on council's site, which is a finding rather than a gap. */
table.grid td .note { display: block; margin: .2rem 0 0; font-size: .8rem; color: var(--stamp); }
ol.deps.compact .who { font-size: .95rem; }
.related.storycard .verdict { margin: .3rem 0 .6rem; }
.related.storycard a { font-family: var(--display); font-weight: 600; }
.pager { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; margin: 1.8rem 0; font-family: var(--mono); font-size: .8rem; }
.pager a, .pager .here {
  min-width: 2.1rem; text-align: center; padding: .35rem .55rem;
  border: 1px solid var(--rule); border-radius: 2px; text-decoration: none;
}
.pager a { background: var(--paper-2); color: var(--ink-soft); }
.pager a:hover { border-color: var(--olive); color: var(--olive-deep); }
.pager .here { background: var(--olive); color: #fff; border-color: var(--olive); font-weight: 600; }
.pager .gap { padding: 0 .15rem; color: var(--ink-faint); }
.pager .of { margin-left: auto; color: var(--ink-faint); font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; }

/* ---------- masthead search ----------
   The index is the biggest thing the site holds; it should not be reachable
   only by first clicking a nav item. */
.navsearch { display: flex; gap: .3rem; margin-left: auto; }
.navsearch input[type=search] {
  font-family: var(--mono); font-size: .76rem; padding: .38rem .55rem;
  width: 11rem; max-width: 46vw; color: var(--ink); background: var(--paper);
  border: 1px solid var(--rule); border-radius: 2px;
}
.navsearch input[type=search]::placeholder { color: var(--ink-faint); }
.navsearch input[type=search]:focus {
  outline: 2px solid var(--olive); outline-offset: 1px; border-color: var(--olive);
}
.navsearch button {
  font-size: .8rem; padding: .3rem .6rem; cursor: pointer; line-height: 1;
  color: #fff; background: var(--olive); border: none; border-radius: 2px;
}
.navsearch button:hover { background: var(--ink); }
@media (max-width: 640px) {
  .navsearch { margin-left: 0; width: 100%; }
  .navsearch input[type=search] { flex: 1; max-width: none; width: auto; }
}
.sortbar { font-family: var(--mono); font-size: .74rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); margin: 0 0 1rem; display: flex; gap: .55rem; flex-wrap: wrap; align-items: baseline; }
.sortbar a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--rule); }
.sortbar a:hover { color: var(--olive-deep); border-bottom-color: var(--olive); }
.sortbar .here { color: var(--ink); border-bottom: 2px solid var(--olive); }

/* ---------- meetings filter (progressive enhancement) ---------- */
.filterbar { display: flex; gap: .35rem; flex-wrap: wrap; align-items: baseline; margin: .5rem 0; }
.filterbar .label { font-family: var(--mono); font-size: .68rem; text-transform: uppercase; letter-spacing: .12em; color: var(--ink-faint); min-width: 3rem; }
.filterbar button {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .05em; padding: .25rem .6rem; cursor: pointer;
  color: var(--ink-soft); background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: 2px;
}
.filterbar button:hover { border-color: var(--olive); color: var(--olive-deep); }
.filterbar button.on { background: var(--olive); color: #fff; border-color: var(--olive); }
/* Subjects (tags.py): links, not filters, so they work without script. */
.filterbar.subjects-bar a {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .05em; padding: .25rem .6rem; text-decoration: none;
  color: var(--ink-soft); background: var(--paper-2);
  border: 1px solid var(--rule); border-radius: 2px;
}
.filterbar.subjects-bar a:hover { border-color: var(--olive); color: var(--olive-deep); }
ol.subject-rows { list-style: none; margin: 0 0 1.5rem; padding: 0; }
ol.subject-rows li { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: .2rem 1rem; padding: .5rem 0; border-bottom: 1px solid var(--rule-soft); }
ol.subject-rows .date { font-family: var(--mono); font-size: .74rem; color: var(--olive-deep); text-transform: uppercase; padding-top: .15rem; }
ol.subject-rows .what { overflow-wrap: anywhere; }
ol.subject-rows .quiet { display: block; font-size: .85rem; }
@media (max-width: 44rem) { ol.subject-rows li { grid-template-columns: minmax(0, 1fr); } }
ul.subject-index { list-style: none; margin: 0 0 1.5rem; padding: 0; }
ul.subject-index li { padding: .6rem 0; border-bottom: 1px solid var(--rule-soft); }
ul.subject-index b { font-family: var(--mono); font-weight: 500; font-size: .8rem; color: var(--ink-soft); margin-left: .4rem; }
ul.subject-index .quiet { display: block; font-size: .9rem; }
.filtercount { font-family: var(--mono); font-size: .72rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: .05em; margin: .6rem 0 1rem; }
.grid .topic { display: block; color: var(--ink-soft); font-size: .9rem; }

/* A published transcript is OUR text, not council's record. The provenance
   banner says which, and the block is set apart so it can never be mistaken
   for the minuted extract above it. */
.note.provenance {
  border-left: 3px solid var(--stamp);
  padding-left: .9rem;
}
.editorial.transcript {
  border-left: 1px solid var(--rule);
  padding-left: 1.1rem;
}
.editorial.transcript p { margin: 0 0 .55rem; }

/* ---------- the menu button ----------
   Hidden on a wide screen, where the whole menu is always on show. */
.menu-toggle { display: none; }

/* ---------- tablets and phones: the menu is a panel ----------
   Four columns do not fit, and a strip that scrolls sideways hid most of the
   registers off the edge of the screen. Instead the Menu button opens every
   destination at once: the site links in a row, then the four register
   groups two to a row, stacked. Nothing scrolls sideways. Without script the
   panel is simply shown open (the .js class never lands). */
@media (max-width: 52rem) {
  .menu-toggle {
    display: inline-flex; align-items: center; gap: .45rem; margin-left: auto;
    font-family: var(--mono); font-size: .8rem; font-weight: 600;
    text-transform: uppercase; letter-spacing: .1em;
    padding: .5rem .8rem; min-height: 2.5rem; cursor: pointer;
    color: var(--ink); background: var(--paper-2);
    border: 1px solid var(--rule); border-radius: 2px;
  }
  .menu-toggle::after { content: "\25BE"; font-size: .9em; }
  .menu-open .menu-toggle { background: var(--olive); color: #fff; border-color: var(--olive); }
  .menu-open .menu-toggle::after { content: "\2715"; }
  .brand-rule { display: none; }
  .masthead nav { order: 3; flex-basis: 100%; gap: .2rem 1.6rem; }
  .masthead .navsearch { order: 4; }
  .masthead .masthead-tag { order: 5; }
  .js .masthead nav, .js .subnav { display: none; }
  .js.menu-open .masthead nav { display: flex; }
  .js.menu-open .subnav { display: block; }
  .subnav nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem 1.5rem; }
  .subnav .wrap { padding-block: .9rem 1.1rem; }
  /* One link per line: each is a target you can hit with a thumb. */
  .subnav .group { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0; }
  .subnav .group-label { flex-basis: auto; align-self: stretch; margin-bottom: .2rem; }
  .masthead .navsearch { margin-left: 0; width: 100%; }
  .masthead .navsearch input[type=search] { flex: 1; max-width: none; width: auto; }
  .subnav nav a { align-self: flex-start; padding-block: .4rem; }
  /* The open panel is for choosing where to go; the strapline can wait. */
  .menu-open .masthead-tag { display: none; }
}
/* Brand and Menu button share one line on a 360px phone. */
@media (max-width: 34rem) {
  .masthead .wrap { column-gap: .5rem; }
  .brand { font-size: .95rem; letter-spacing: .08em; }
  .menu-toggle { padding: .45rem .65rem; }
}

/* Whether the person actually spoke: the one question every deputation
   page must answer before anything else. */
p.heard { margin: 0 0 1rem; padding: .55rem .8rem; background: var(--paper-2); border-left: 3px solid var(--olive); }

/* A minuted question and its answer, laid out as council printed them:
   the question numbered, the answerer named on a line of their own, and
   the answer set off by a rule so the two voices never run together. */
.minuted .minuted-num {
  font-family: var(--mono); font-size: .74rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em; color: var(--ink-faint);
  margin: 2rem 0 .4rem; padding-top: .9rem; border-top: 1px solid var(--rule);
}
.minuted .minuted-num:first-child { margin-top: .5rem; }
.minuted .minuted-by {
  font-family: var(--mono); font-size: .78rem; color: var(--olive-deep);
  margin: 1.1rem 0 .5rem; padding-left: .8rem; border-left: 3px solid var(--olive);
}
.minuted .minuted-a { padding: .35rem 0 .35rem .8rem; border-left: 3px solid var(--rule-soft); margin: 0; }
.minuted ul.minuted-a { padding-left: 2rem; }
.minuted p.minuted-q { font-weight: 600; }
.minuted .minuted-field { margin: .25rem 0; }
.minuted .minuted-field span {
  font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--ink-faint); margin-right: .4rem;
}
.minuted ul { margin: .4rem 0 .8rem; }
.minuted li { margin: .3rem 0; }

/* ---------- the phone ----------
   Last in the file on purpose. These are floors, and a floor only holds if it
   is the last thing said: .pill, .sortbar and the sub-nav are all declared
   further down than the narrow-viewport block above, so an override placed
   there lost to them on specificity and left the type at 10.6px. */
@media (max-width: 34rem) {
  /* The mono microcopy is set small so it stays subordinate on a wide page. On
     a phone .66-.74rem lands at 10.6-11.8px, below what anyone should have to
     read at arm's length -- 102 of the labels on /deputations/ were 11.2px.
     The floor keeps the hierarchy, because the body it defers to is 17px. */
  .counter span, table.grid th, .doc, a.tiny, .pill, .filtercount, .meta,
  p.meta, p.meta a, .filterbar .label, .filterbar button, .subnav-label,
  .sortbar, .pager .of, figure.chart figcaption, .foot .meta,
  .navsearch input[type=search], table.grid.legal .closed,
  table.grid td .note, ul.doc-series .meta { font-size: .8rem; }

  /* Navigation is the one place on this site where a link is a control rather
     than a word in a sentence, so it gets a target you can hit. 24px is the
     floor WCAG 2.2 sets and these sat exactly on it; prose links are exempt
     and stay as they are. */
  .masthead nav a, .subnav nav a { font-size: .8rem; padding-top: .32rem; padding-bottom: .44rem; }


  /* An agenda row is [item number] [title] [cue the video]. Below about 340px
     the three do not fit on one line, and the video chip -- which must not
     break, it is a timestamp -- took 41 meeting pages sideways with it. Letting
     the row wrap drops the chip under the title it belongs to. */
  /* minmax(0,…) not 1fr: a bare 1fr keeps an auto minimum and the label's
     width would push two columns past the viewport. */
  .registers { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .registers a { min-width: 0; }
  /* A group of three leaves an empty cell in a two-column grid; let the
     odd last tile take the row. */
  .registers a:last-child:nth-child(odd) { grid-column: 1 / -1; }
  .registers a { padding: .7rem .75rem .8rem; }
  .registers small { font-size: .82rem; }
  .masthead-tag { font-size: .86rem; }
  ol.agenda .row { flex-wrap: wrap; gap: .45rem .9rem; }
  ol.agenda .iname { flex: 1 1 55%; min-width: 0; }
}

/* ---------------------------------------------------------- local laws --
   A statute is a tree, and reading one means knowing where in the tree you
   are. The sidebar holds the place; the indented blocks show the nesting;
   an example or a penalty is set apart so it cannot be mistaken for the
   rule it illustrates.

   minmax(0, 1fr) on both the page grid and the paragraph grid is what stops
   a five-deep clause or a long lot description pushing the page sideways on
   a phone. A bare 1fr will not shrink below its content. */
.law, .reader { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 2.5rem;
       margin-top: 1.5rem; }
.law-toc, .reader-toc { position: sticky; top: 1rem; align-self: start;
           max-height: calc(100vh - 2rem); overflow-y: auto;
           font-size: .82rem; line-height: 1.35;
           border-left: 2px solid var(--rule, #ddd); padding-left: .9rem; }
.law-toc-head, .reader-toc-head { font-family: var(--sans, inherit); text-transform: uppercase;
                letter-spacing: .06em; font-size: .7rem; margin: 0 0 .5rem; }
.law-toc ul, .reader-toc ul { list-style: none; margin: 0; padding: 0; }
.law-toc li, .reader-toc li { margin: .15rem 0; }
.law-toc li.d1, .reader-toc li.d1 { padding-left: .7rem; }
.law-toc li.d2, .law-toc li.d3, .reader-toc li.d2 { padding-left: 1.4rem; }
.law-toc li.s a, .reader-toc li.s a { color: inherit; }
.law-toc a, .reader-toc a { text-decoration: none; }
.law-toc a:hover, .law-toc a:focus, .reader-toc a:hover, .reader-toc a:focus { text-decoration: underline; }

.law-body, .reader-body { min-width: 0; overflow-wrap: anywhere; }
.law-head { margin: 2rem 0 .6rem; }
.law-kind { display: block; font-size: .72rem; text-transform: uppercase;
            letter-spacing: .08em; color: var(--ink-soft, #666); }
.law-section { margin: 1.4rem 0; }
.law-section h4 { margin: 0 0 .4rem; font-size: 1rem; }
.law-num { font-family: var(--mono, monospace); }
.law-link, .law-page { font-size: .75rem; font-weight: normal;
                       text-decoration: none; margin-left: .4rem; }
.law-link { opacity: 0; }
.law-section h4:hover .law-link, .law-link:focus { opacity: 1; }

/* Both columns can shrink to nothing. A fixed label column looks tidier
   until council reaches paragraph (viii) five levels down, which is wider
   than the column and pushes the page sideways on a phone; an auto column
   solves that and then grows instead. minmax(0, ...) with a label that may
   wrap is the only form that cannot overflow at any depth or width. */
.prov { display: grid; grid-template-columns: minmax(0, 2.9rem) minmax(0, 1fr);
        column-gap: .4rem; margin: .3rem 0 .3rem .8rem; }
.prov .lbl { font-family: var(--mono, monospace); font-size: .85rem;
             padding-top: .1rem; overflow-wrap: anywhere; }
.prov p { margin: 0 0 .3rem; }

.law-aside { font-size: .9rem; color: var(--ink-soft, #555);
             border-left: 2px solid var(--rule, #ddd);
             padding-left: .8rem; margin: .4rem 0 .6rem 1.2rem; }
dl.facts { display: grid; grid-template-columns: minmax(8rem, 12rem) 1fr;
           gap: .35rem 1.2rem; margin: 1rem 0 1.5rem; }
dl.facts dt { font-family: var(--mono); font-size: .72rem; text-transform: uppercase;
              letter-spacing: .06em; color: var(--ink-soft); padding-top: .3rem; }
dl.facts dd { margin: 0; }
@media (max-width: 44rem) { dl.facts { grid-template-columns: 1fr; gap: .1rem; }
                            dl.facts dd { margin-bottom: .6rem; } }
.h1-sub { display: block; font-size: .55em; font-weight: 500; margin-top: .3rem; }
.da-list { list-style: none; padding: 0; }
.da-list li { margin: .35rem 0; }
.da-mentions .snip { margin: .3rem 0 .2rem; }
.law-table { margin: .8rem 0 1rem; overflow-x: auto; }
.law-table table { overflow-wrap: normal; }
.law-table th { text-align: left; vertical-align: bottom; }
.law-table td { vertical-align: top; }
.law-map { margin: .5rem 0; padding-left: .8rem;
           border-left: 2px solid var(--rule, #ddd); }
.law-map .law-kind { display: inline; margin-right: .3rem; }
/* .law-body's overflow-wrap: anywhere lets a table column shrink to one
   character; the meeting column must hold a date on one line. */
table.law-cited td.date { white-space: nowrap; overflow-wrap: normal;
                          padding-right: 1rem; }
@media (min-width: 44.01rem) { table.law-cited td.date { width: 1%; } }
table.law-cited td.date .law-sub { white-space: normal; }
.law-def { margin: .5rem 0; }
.law-terms { list-style: none; padding: 0;
              columns: 2; column-gap: 2rem; }
.law-terms li { margin: 0 0 .5rem; break-inside: avoid; }
@media (max-width: 52rem) { .law-terms { columns: 1; } }
.law-history { padding-left: 1.1rem; }
.law-history li { margin: .4rem 0; }
.law-history .date { font-family: var(--mono, monospace); font-size: .85rem;
                     margin-right: .4rem; }
.law-spoken { margin-top: 1rem; }
.law-spoken summary { cursor: pointer; font-size: .9rem; }
.law-spoken li { margin: .5rem 0; }

@media (max-width: 52rem) {
  .law, .reader { display: block; }
  .law-toc, .reader-toc { position: static; max-height: none;
             margin-bottom: 1.5rem; overflow-y: visible; }
  .prov { margin-left: .4rem; column-gap: .3rem;
          grid-template-columns: minmax(0, 2rem) minmax(0, 1fr); }
  .law-aside { margin-left: .6rem; }
}

/* Council nests to five levels in places (schedule 10's advertising rules
   reach paragraph (b)(ii)(G), and Local Law 1's schedule 2 goes deeper still
   where OCR lost a label). Past the fourth level the indent stops growing.
   Deeper than that on a phone the two-column form is abandoned entirely and
   the label sits above its text: at 320px the text column had been squeezed
   to nothing, and a paragraph zero pixels wide pushes the whole page
   sideways. */
.prov .prov .prov .prov { margin-left: 0; }
@media (max-width: 52rem) {
  .prov .prov { margin-left: 0; }
  .prov .prov .prov .prov { display: block; }
  .prov .prov .prov .prov > .lbl { display: inline-block; margin-right: .3rem; }
  .law-toc, .reader-toc { max-height: 18rem; overflow-y: auto; }
}

/* A one-line qualifier inside a table cell. The site's .note is a callout
   with its own rule and padding, which in a cell triples the row height and
   turns a register into a wall. */
.law-sub { display: block; font-size: .78rem; color: var(--ink-soft, #666);
           margin-top: .15rem; }

/* ---------- votes: three kinds of record, never one ----------
   The whole votes section turns on a reader being able to tell a name council
   wrote down from a name this site worked out. Prose says so, but prose is
   skipped: these badges put the distinction in every cell that carries a
   number, and they are weighted deliberately - solid for what council
   recorded, hollow for what was inferred, stamped for what was never written.
   They must survive being read in a hurry. */
.vote-recorded, .vote-inferred, .vote-none, .vote-for, .vote-against {
  font-family: var(--mono); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .06em; padding: .1rem .4rem; white-space: nowrap;
  border: 1px solid currentColor; display: inline-block; line-height: 1.5;
}
.vote-recorded { background: var(--ink); color: var(--paper); border-color: var(--ink); }
/* "For" is the common case and runs hundreds deep down a councillor's page.
   Solid ink that many times reads as a redaction block rather than a vote, so
   it is outlined and only "against" is stamped. */
.vote-for { color: var(--ink-soft); background: none; }
/* Hollow, and hatched like the redaction bars: an inference is a reading of
   the record, not the record. */
.vote-inferred { color: var(--ink-soft); background:
  repeating-linear-gradient(135deg, transparent 0 4px, var(--rule-soft) 4px 5px); }
.vote-none, .vote-against { color: var(--stamp); background: var(--stamp-soft); border-color: var(--stamp); }

/* The by-year bar carries all three shares in one row, in the same order as
   the table above it, so the 2016 and 2017 rows read as one solid block of
   "not recorded" without needing a legend read first. */
td.bar.regime { display: flex; gap: 1px; align-items: stretch; padding-top: .55rem; padding-bottom: .55rem; }
td.bar.regime span { display: block; height: .85rem; min-width: 2px; background-image: none; }
td.bar.regime span.named { background-color: var(--ink); }
td.bar.regime span.inferred { background-color: var(--ink-soft); opacity: .45; }
td.bar.regime span.none { background-color: var(--stamp); }
tr:hover td.bar.regime span.named { background-color: var(--ink); }

/* A motion's own words, under the item title: useful when the title is a
   council file heading that says nothing, but never louder than the title. */
.motion { display: block; font-size: .85rem; margin-top: .2rem; max-width: 46rem; }
/* Used in the interests tables inside a list; the votes tables need it as a
   plain inline note beside an outcome. */
td .replaced, td.quiet .replaced {
  display: inline-block; color: var(--stamp); font-size: .78rem;
  font-family: var(--mono); text-transform: uppercase; letter-spacing: .05em;
}
td .num { font-variant-numeric: tabular-nums; font-weight: 600; margin-right: .3rem; }
td.side { white-space: nowrap; }

/* The contested-votes table. Two columns of names are the reason the page
   exists, so they get the room; the motion text is context and is allowed to
   wrap as tall as it likes inside a narrow column. */
.votes-table { table-layout: fixed; width: 100%; }
.votes-table .c-date { width: 13%; }
.votes-table .c-what { width: 33%; }
.votes-table .c-side { width: 22%; }
.votes-table .c-outcome { width: 12%; }
.votes-table td { overflow-wrap: anywhere; }
/* td.date is nowrap site-wide, which is right for a bare date and wrong for a
   date plus a committee name: in a fixed-layout table it ran straight over
   the next column. The committee takes its own line instead. */
.votes-table td.date { white-space: normal; }
.votes-table td.date .quiet { display: block; }
/* Jinja trims the newline after a block tag, so inline badges and links would
   otherwise sit flush against the last word of the title. */
.blocktype, a.tiny.ts, td .replaced { margin-left: .4rem; }
a.ts { font-variant-numeric: tabular-nums; }

/* Stacked tables in the votes section.
   .stack turns every cell into a block, which would flatten the three-part
   regime bar and stand the councillor tallies in a column. Both want to keep
   their own shape inside the card. */
/* 44rem, to match the breakpoint where .stack takes over. The overrides below
   must also out-specify `table.grid.stack td.num`, which pins a cell right
   with margin-left:auto - at 390px that pushed the labelled tallies off the
   edge and clipped the inferred count, which is the one number on this page
   that must never go missing. */
@media (max-width: 44rem) {
  table.grid.stack td.bar.regime { display: flex; flex-basis: 100%; margin-top: .4rem; }
  /* Labelled tallies read left to right like a sentence, not as a right-hand
     column: the label is beside the number, so the alignment carries nothing. */
  /* One tally per line. Sharing a line was tried twice and both times a
     three-digit count was squeezed out of its cell and printed underneath the
     next badge - "787INFERRED" - because the badge inside is nowrap and will
     not give up width. A tally that is wrong to read is worse than a tall
     card, and the inferred count is the one number on this page that must
     never go missing. */
  table.grid.stack.votes-people td.num {
    margin-left: 0; text-align: left; font-weight: 600;
    font-variant-numeric: tabular-nums; flex-basis: 100%;
    min-width: max-content;
  }
  /* One box for all three labels so the counts line up down the card. The
     contested badge needs spelling out: min-width does nothing to an inline
     box, and .blocktype carries a .4rem left margin elsewhere that shifted it
     off the other two. */
  table.grid.stack.votes-people td.num .vote-recorded,
  table.grid.stack.votes-people td.num .vote-inferred,
  table.grid.stack.votes-people td.num .blocktype {
    display: inline-block; min-width: 6.2rem; text-align: left;
    padding: .1rem .4rem; border: 1px solid transparent; margin-left: 0;
  }
  table.grid.stack.votes-people td.when { flex-basis: 100%; }
  /* Same trap on the by-year table: the two tallies now carry their own
     labels, so they read left to right too. */
  /* Two labelled tallies on one line. They fit with room to spare; what was
     missing was any space between them, so the year's contested count ran
     straight on from the word DECISIONS. Padding rather than gap, because the
     cell is what has to carry it. */
  /* The year cell inherits a date column's minimum width, which is sized for
     "20 August 2026" and leaves a bare "2016" holding 104px of a 327px row.
     Reclaiming it is what lets both tallies sit on one line. */
  table.grid.stack.chart td.date { min-width: 0; padding-right: .75rem; }
  table.grid.stack.chart td.num {
    margin-left: 0; text-align: left; flex: 0 0 auto; padding-right: .75rem;
    /* flex-shrink:0 was not enough: measured in the browser the cell came out
       88px against a scrollWidth of 100, so the text spilled over the next
       tally with no space between them. min-width holds the box open to its
       own content. */
    min-width: max-content;
  }
}
/* The span of service is a date range, not a number: on a wide screen it sits
   quietly beside the name the way the old .quiet cell did. */
.votes-people td.when { color: var(--ink-soft); }
/* A column name repeated inside the cell, for when the header row is hidden.
   Shown only where that happens, so a wide table is not captioned twice. */
.colname { display: none; font-family: var(--mono); font-size: .68rem;
           text-transform: uppercase; letter-spacing: .06em; color: var(--ink-soft); }
@media (max-width: 44rem) { table.grid.stack .colname { display: inline; } }
/* An amendment or a procedural motion is a kind of decision, not a fault.
   Neutral, where .replaced is the site's red for something gone wrong. */
.blocktype {
  font-family: var(--mono); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink-soft); white-space: nowrap;
}
a.more { font-family: var(--mono); font-size: .8rem; text-transform: uppercase; letter-spacing: .06em; }


/* ---- Reading a meeting transcript -------------------------------------
   A six-hour meeting is 370 one-minute passages. Rendered as search results
   that is nineteen pages and no way to tell which one holds the item you
   came for; rendered here it is one document with council's own agenda
   bookmarks as chapters, and ctrl-F works across the whole meeting.

   The text is machine transcription and is set to read as such: the same
   body face as an ordinary page, but every passage keeps its timestamp in
   the margin, because the timestamp is the part that is reliable. */
.reader { margin-top: 1rem; }
.reader-toc .ts { font-family: var(--mono, monospace); font-size: .72rem;
                  color: var(--ink-soft, #666); margin-right: .35rem; }
.reader-toc .outline { font-family: var(--mono, monospace); font-size: .72rem; }
.reader-toc li.d2 { font-size: .95em; font-style: italic; }
.reader-toc .hint { display: block; font-size: .72rem; color: var(--ink-soft, #666);
                    margin: 0 0 .6rem; font-style: italic; }

.chapter { margin: 0 0 2.2rem; scroll-margin-top: 1rem; }
.chapter h2 { font-size: 1.05rem; margin: 0 0 .25rem; line-height: 1.3; }
.chapter h2 .outline { font-family: var(--mono, monospace); }
.chapter h2:hover .law-link, .chapter .law-link:focus { opacity: 1; }
.chapter > .meta { margin: 0 0 .8rem; }
.chapter.floor h2 { font-style: italic; }

/* The timestamp is a link into council's recording, so it has to look like
   one at a glance without turning a wall of passages into a wall of blue. */
.passage { display: grid; grid-template-columns: minmax(0, 4.2rem) minmax(0, 1fr);
           column-gap: .7rem; margin: 0 0 .5rem; scroll-margin-top: 1rem; }
.passage .ts { font-family: var(--mono, monospace); font-size: .78rem;
               color: var(--ink-soft, #666); padding-top: .18rem;
               text-decoration: none; }
.passage .ts:hover, .passage .ts:focus { text-decoration: underline; }
.passage:target .said { background: var(--mark, #fdf3c8); }
/* Who is speaking, printed where the voice changes. A numbered voice is
   greyed: it marks a change of speaker without claiming to know who. */
.passage .who { display: block; margin-top: .3rem; font-family: var(--sans, inherit);
                font-size: .85rem; font-weight: 600; }
.passage .runs > .who:first-child { margin-top: 0; }
.passage .who[title] { text-decoration: underline dotted; text-underline-offset: .2em; cursor: help; }
.passage .who.anon { font-weight: 400; color: var(--ink-soft, #666); }

/* Carried unanimously and carried 4-2 are different facts about how a
   council governs. The chip carries the division count too, because an item
   that took seven divisions was a fight and the final tally alone hides it. */
.chip { display: inline-block; font-family: var(--sans, inherit); font-size: .68rem;
        text-transform: uppercase; letter-spacing: .04em; padding: .05rem .35rem;
        border: 1px solid var(--rule, #ddd); border-radius: 2px;
        margin-left: .35rem; white-space: nowrap; color: var(--ink-soft, #555); }
.chip.lost { border-color: #b5484a; color: #9e3d3f; }

.sources.inline { list-style: none; padding: 0; display: flex; flex-wrap: wrap;
                  gap: .4rem 1.1rem; font-size: .9rem; margin: .6rem 0 1rem; }
form.search.within { margin: 0 0 1.4rem; }

/* A pager at the foot only means scrolling a six-hour meeting to find out how
   much of it there is. */
.pager.top { margin: 0 0 1.2rem; }

@media (max-width: 52rem) {
  .passage { grid-template-columns: minmax(0, 3.6rem) minmax(0, 1fr);
             column-gap: .5rem; }
}

/* /confidential/<year>/: the item list sits level with its date. */
ul.conf-items { margin: 0; }
ul.conf-items li:first-child { border-top: 0; padding-top: 0; }

/* Who votes with whom (/votes/alignment/). The shade is the same-side share,
   capped so the numbers stay readable in both themes; the number is always
   printed, so the colour is never the only carrier of the fact. */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden;
                   clip: rect(0 0 0 0); white-space: nowrap; }
.align-wrap { max-width: 100%; overflow-x: auto; margin: 1rem 0 1.5rem; }
.align { border-collapse: separate; border-spacing: 2px; font-family: var(--display);
         font-size: .8rem; }
.align th { font-weight: 600; text-align: right; padding: 0 .4rem 0 0; white-space: nowrap; }
.align thead th { text-align: center; padding: 0 0 .3rem; }
.align td { width: 3.4rem; height: 2.6rem; text-align: center; padding: 0;
            border: 1px solid var(--rule-soft); }
.align td a { display: flex; flex-direction: column; justify-content: center; height: 100%;
              color: var(--ink); text-decoration: none; font-weight: 600; }
.align td a:hover, .align td a:focus { outline: 2px solid var(--olive-deep); }
.align td small { font-weight: 400; font-size: .68rem; color: var(--ink-soft); }
.align-cell { background: color-mix(in srgb, var(--olive) calc(var(--s) * var(--s) * 75%), var(--paper)); }
.align-thin a { color: var(--ink-soft); font-weight: 400; }
.align-self { background: var(--rule-soft); border-color: transparent; }
.align-none { color: var(--ink-faint); }
.align-pair { border-top: 1px solid var(--rule-soft); padding: .45rem 0; scroll-margin-top: 1rem; }
.align-pair summary { cursor: pointer; }
.align-pair h4 { margin: .7rem 0 .3rem; font-size: .85rem; }
.align-list { margin: 0 0 .5rem; padding-left: 1.1rem; }
.align-list li { margin: .25rem 0; }
.align-list .date { font-family: var(--mono); font-size: .78rem; margin-right: .35rem; }
@media (max-width: 40rem) {
  .align { font-size: .72rem; border-spacing: 1px; }
  .align td { width: 2.3rem; height: 2.3rem; }
  .align td small { display: none; }
  .align thead th span { writing-mode: vertical-rl; transform: rotate(180deg); }
  .align thead th { vertical-align: bottom; }
}
