/* ===========================================================================
   Sector Events Calendar
   ---------------------------------------------------------------------------
   The design system is NNTC's, because that is where this calendar is mostly
   read: framed into nntc.com.au and mabocentre.com. Tokens, typeface, button
   shapes and control shapes are taken from the NNTC stylesheet unchanged, so a
   row rendered here and a row rendered there are the same row rather than two
   that resemble each other.

   Only what this theme actually renders is here. The earlier sheet was the
   whole NNTC site stylesheet with sections lifted out of it, which is how
   `.cal` ended up meaning two different things — a list on the homepage module
   and the page section here — and drew a stray rule across the page.
   =========================================================================== */

/* ── Typeface ──────────────────────────────────────────────────────────────
   Season Sans is the brand face. Paths are relative to this file, which lives
   in assets/, so they are fonts/… and not assets/fonts/… — the sheet this was
   copied from sat at the web root. Without these the calendar renders in the
   system fallback, which is the single most visible way an embed stops looking
   like the page it is embedded in. */
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-Light.ttf") format("truetype");    font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-Regular.ttf") format("truetype");  font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-Medium.ttf") format("truetype");   font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-SemiBold.ttf") format("truetype"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-Bold.ttf") format("truetype");     font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Season Sans"; src: url("fonts/SeasonSans-Heavy.ttf") format("truetype");    font-weight: 900; font-style: normal; font-display: swap; }

/* ── Tokens ───────────────────────────────────────────────────────────────── */
:root {
  --sand:   #f1eae8;   /* page background          */
  --ink:    #2b2e34;   /* dark cards, header, text */
  --accent: #b0aaf8;   /* primary button           */
  --deep:   #2b2e34;   /* header bar, ack panel    */
  --olive:  #616c29;   /* acknowledgement panel    */
  --ochre:  #bc6f2a;   /* accents, Mabo Centre     */
  --rule:   rgba(43, 46, 52, .35);
  --field:  #fff;      /* form field fill          */

  --shell:  1268px;
  --radius: 24px;
  --font:   "Season Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* The header is fixed, so every section that starts at the top of a page
     clears it from one number rather than from a guess per page. */
  --headroom: 5.25rem;
}

/* ── Whose design is this? ────────────────────────────────────────────────
   Two answers, and they are different answers.

   **Framed**, the calendar is a guest in somebody else's page. A guest dresses
   like the host, so the values at :root above are NNTC's, unchanged, and the
   listing that gets framed keeps them. That is the whole point of the embed.

   **On its own site**, the calendar is not NNTC's and not the Mabo Centre's —
   it is jointly owned and equally managed, and it should look like it. Wearing
   one partner's design system whole makes the other a visitor to a calendar
   they half own.

   So the site's own pages take a palette that is neither and recognisably both:
   the ground sits between NNTC's warm sand and the Mabo Centre's near-white;
   the ink between NNTC's near-black and the Mabo Centre's aubergine; the accent
   between NNTC's lilac and the Mabo Centre's orchid. Nobody's colour, and both
   organisations' colour. */
body:not(.is-embed) {
  --sand:   #f3efee;   /* ground — NNTC #f1eae8, Mabo Centre #f5f5f5           */
  --ink:    #342e46;   /* text and chrome — NNTC #2b2e34, Mabo Centre #3d2e57  */
  --accent: #ba98f7;   /* primary — NNTC #b0aaf8, Mabo Centre #c385f5          */
  --deep:   #2f2740;   /* the header bar and the Acknowledgement panel         */
  --rule:   rgba(52, 46, 70, .32);
}

/* The Mabo Centre's own palette, for a framed copy that asks for it — its
   actual aubergine and orchid, taken from mabocentre.com, not an invention. */
body.brand-mabo {
  --sand:   #f5f5f5;
  --ink:    #3d2e57;
  --accent: #c385f5;
  --deep:   #3d2e57;
  --ochre:  #fc6982;
  --rule:   rgba(61, 46, 87, .32);
}

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

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

body {
  margin: 0;
  overflow-x: hidden;
  overflow-x: clip;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font);
  font-size: 18px;
  line-height: 1.55;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
h1, h2, h3 { margin: 0; font-weight: 400; line-height: 1.2; }
a { color: inherit; }
p { margin: 0 0 1.25em; }
p:last-child { margin-bottom: 0; }

.shell {
  width: min(100% - 3rem, var(--shell));
  margin-inline: auto;
}

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

/* ── Buttons ──────────────────────────────────────────────────────────────── */
/* Neither organisation's button. NNTC's is a 10px rectangle set in letterspaced
   uppercase; the Mabo Centre's is a full pill in sentence case. This takes the
   pill from one and the weight and size from the other, and drops the shouting:
   sentence case reads as an invitation, which is what "Submit an event" is. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .8rem 1.6rem;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--ink);
  font-family: var(--font);
  font-size: .9375rem;
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: filter .18s ease, transform .18s ease;
}

/* Framed, it goes back to being NNTC's button, because framed it is sitting in
   NNTC's page under NNTC's heading. */
.is-embed .btn {
  padding: .85rem 1.5rem;
  border-radius: 10px;
  font-size: .8125rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.btn:hover  { filter: brightness(1.07); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }

.btn--ghost { background: transparent; border: 1px solid var(--ink); }
.btn--ghost:hover { background: rgba(43, 46, 52, .06); filter: none; }

/* ── Header ───────────────────────────────────────────────────────────────── */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  padding: 1.1rem 0;
  transition: background-color .25s ease;
}
.site-header.is-solid { background: var(--deep); }
/* Over a hero the bar starts transparent and fills in once the page has moved
   past the photograph — a solid slab laid across the top of a picture is the
   thing the photograph was chosen to avoid. */
.site-header.is-stuck { background: var(--deep); }
.site-header:not(.is-solid)::before {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(20, 22, 26, .45), rgba(20, 22, 26, 0));
  content: "";
  opacity: 1;
  transition: opacity .25s ease;
  pointer-events: none;
}
.site-header.is-stuck::before { opacity: 0; }
/* Nothing to shadow against once the bar is filled in. */
.site-header.is-solid .logo__word,
.site-header.is-stuck .logo__word { text-shadow: none; }

.site-header__inner {
  position: relative;   /* above the scrim below, which is positioned */
  display: flex;
  align-items: center;
  gap: 0;
}

/* The calendar belongs to both organisations, so it carries neither logo. The
   wordmark is text, which also means it reads correctly in either palette. */
.logo { display: flex; align-items: center; text-decoration: none; }

/* Two-tone, which is how the Mabo Centre sets its own wordmark, but in NNTC's
   quiet letterspaced caps rather than its heavy condensed ones. The calendar has
   no logo of its own and should not borrow either organisation's, so the
   wordmark is the only mark it has — it may as well say whose it is. */
.logo__word {
  margin: 0;
  color: var(--sand);
  /* The wordmark is the site's only identity — it has no logo to fall back on
     — so it carries its own legibility over a photograph rather than relying on
     the scrim, which a bright sky can still beat. */
  text-shadow: 0 1px 6px rgba(20, 22, 26, .55);
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.logo__word b { font-weight: inherit; color: var(--accent); }

/* NNTC runs a hairline from the wordmark to the navigation. The Mabo Centre
   runs nothing and lets the bar breathe. This keeps the rule but stops it short
   of the links, so it reads as a join rather than a ruled table. */
.site-header__rule {
  flex: 1;
  height: 1px;
  margin: 0 2rem;
  background: currentColor;
  color: var(--sand);
  opacity: .3;
}

/* Plain links and a single pill, the Mabo Centre's arrangement, rather than
   NNTC's bordered oval wrapped around the whole navigation. It also removes the
   oval-inside-an-oval this site had, since it carries one link. */
.nav {
  display: flex;
  align-items: center;
  gap: .5rem;
}
.nav--bare { border: 0; padding: 0; }

.nav__list {
  display: flex;
  align-items: center;
  gap: .25rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__list a,
.nav__contact {
  display: block;
  padding: .65rem 1.05rem;
  color: var(--sand);
  font-size: .9375rem;
  font-weight: 500;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
}
.nav__list a:hover { opacity: .75; }
.nav__contact {
  background: var(--accent);
  color: var(--ink);
  border-radius: 999px;
  padding-inline: 1.35rem;
}
.nav--bare .nav__contact { margin-left: 0; }
.nav__contact:hover { filter: brightness(1.07); }
.nav__list a:focus-visible,
.nav__contact:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* ── Page head ────────────────────────────────────────────────────────────── */
.calhead {
  padding: calc(var(--headroom) + clamp(1.75rem, 1rem + 2.5vw, 3.25rem)) 0 clamp(2rem, 1.5rem + 2vw, 3rem);
}
/* The listing below carries its own top padding and its own ground, which is
   what marks the boundary — so the head does not also pad down into it. */
.calhead:has(+ .events) { padding-bottom: clamp(1.5rem, 1.25rem + 1vw, 2.25rem); }
.calhead__eyebrow {
  margin: 0 0 .9rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.calhead h1 {
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  line-height: 1.1;
  max-width: 20ch;
  margin-bottom: 1rem;
}
.calhead__lead { margin: 0; max-width: 56ch; font-size: 1.0625rem; line-height: 1.6; }

/* ── Setup and empty-state notices ────────────────────────────────────────
   Deliberately plain and unmistakably a notice, so an empty calendar is never
   mistaken for a working one with nothing in it. */
.calsetup {
  margin: 0 0 3rem;
  padding: clamp(1.25rem, 1rem + 1.5vw, 2rem);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ochre);
  background: var(--field);
}
.calsetup h2 {
  margin-bottom: .75rem;
  font-size: clamp(1.1875rem, 1.05rem + .5vw, 1.375rem);
  font-weight: 500;
  line-height: 1.25;
}
.calsetup p { line-height: 1.65; }
.calsetup ol { margin: 1rem 0 0 1.15rem; padding: 0; }
.calsetup li { margin-bottom: .5rem; line-height: 1.6; }
.calsetup code {
  font-size: .9em;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  padding: .1em .35em;
  border-radius: 3px;
}
.calsetup__done { border-left-color: var(--olive); }

/* An empty calendar's notice sits below the count rule rather than against it. */
.cal > .shell > .calsetup { margin-top: 2.5rem; }

/* ── The listing ──────────────────────────────────────────────────────────
   The Sector Events Calendar section of the NNTC site, taken from its
   stylesheet unchanged. This is the component both consuming websites frame,
   so it is the component this site renders too — the calendar's own front page
   is the same markup with a heading above it rather than a second design.

   Hairline rules, no cards, and no month bands. The sector publishes a handful
   of events at a time; a full-bleed photograph announcing a month that holds
   one event is a chapter heading on a page with one paragraph. Rows can be
   separated without being fenced, and a short list reads best unfenced. */

.events { padding: 3.5rem 0 4rem; background: #ece4e1; }

/* Filters. Native selects on purpose — they are keyboard and screen-reader
   correct for free, they collapse to the platform picker on a phone, and they
   are the control The Events Calendar's own Filter Bar renders anyway.
   Shaped like the host's, though: NNTC's news and resources filters are pills
   with an uppercase label over them that fill with ink once they are set, and
   the framed calendar sits twenty pixels below a set of them. A rounded
   rectangle and a lower-case label read as a second product on the same page.
   The shape is taken from there and the colour from the tokens, so the Mabo
   Centre's framed copy gets the same pill in its own aubergine. */
.events__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem 1.25rem;
  margin: 0 0 1.25rem;
}

.filt { display: flex; flex-direction: column; gap: .4rem; margin: 0; }

.filt__label {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.filt__select {
  appearance: none;
  min-width: 11rem;
  /* 44px tall, which is the smallest thing a thumb hits reliably. */
  min-height: 44px;
  padding: .55rem 2.5rem .55rem 1.15rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: transparent;
  /* Chevron drawn inline so the control needs no image request. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%232b2e34' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05rem center;
  background-size: 12px 8px;
  color: var(--ink);
  font-family: var(--font);
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .12s, border-color .12s, color .12s;
}
.filt__select:hover { background-color: color-mix(in srgb, var(--ink) 7%, transparent); }
.filt__select:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* A dropdown is bad at saying it has been changed — the label reads the same
   whether it is set or not. Set, the pill fills with ink, which is how the
   same control says so on the page this is framed into. The chevron has to be
   redrawn light, because it is painted into the background image. */
.filt__select.is-on {
  background-color: var(--ink);
  border-color: var(--ink);
  color: var(--sand);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23f1eae8' stroke-width='1.5'/%3E%3C/svg%3E");
}
/* The open list is the operating system's, so it is given the page's own
   ground rather than whatever the platform defaults to behind an ink pill. */
.filt__select option { background: var(--sand); color: var(--ink); }

.filt__reset {
  padding: .7rem 0;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--font);
  font-size: .875rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* Upcoming or everything. Upcoming is the default because a calendar that
   opens on things already held is answering the wrong question. Only the
   calendar's own page carries it; the framed copy shows what is coming. */
.calseg { display: inline-flex; border: 1px solid var(--rule); border-radius: 100px; overflow: hidden; }
.calseg__btn {
  appearance: none;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: .8125rem;
  letter-spacing: .04em;
  padding: .7rem 1.1rem;
  cursor: pointer;
  color: color-mix(in srgb, var(--ink) 70%, transparent);
}
.calseg__btn.is-on { background: var(--ink); color: var(--sand); }
.calseg__btn:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }

.events__count {
  margin-bottom: 1.5rem;
  font-size: .875rem;
  opacity: .7;
}

.cal {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rule);
}

.cal__row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr) auto;
  align-items: start;
  gap: 1.5rem 2rem;
  padding: 1.6rem 0;
  border-bottom: 1px solid var(--rule);
}
.cal__row[hidden] { display: none; }

.cal__date {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  color: var(--olive);
  line-height: 1;
}
.cal__day { font-size: 2.35rem; letter-spacing: -.02em; }
.cal__range { font-size: 1.35rem; }
.cal__mon {
  margin-top: .35rem;
  font-size: .875rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.cal__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .75rem;
  margin-bottom: .55rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* Host is the one piece of metadata that must never be ambiguous on a shared
   calendar, so it is the only one that carries colour. A member body's own
   name carries none and simply reads as itself. */
.cal__host { padding-right: .75rem; border-right: 1px solid var(--rule); }
.cal__host--nntc { color: var(--olive); }
.cal__host--mabo { color: var(--ochre); }
.cal__type, .cal__tag { opacity: .65; }

.cal__status {
  padding: .15rem .5rem;
  border-radius: 4px;
  background: var(--ochre);
  color: var(--sand);
  letter-spacing: .06em;
}

.cal__title {
  font-size: clamp(1.15rem, 1.05rem + .4vw, 1.45rem);
  line-height: 1.3;
  margin-bottom: .45rem;
}
.cal__title a { text-decoration: none; }
.cal__title a:hover { text-decoration: underline; text-underline-offset: 3px; }

.cal__where { margin: 0; font-size: .95rem; line-height: 1.5; opacity: .75; }
.cal__where--tbc { font-style: italic; opacity: .8; }

.cal__add {
  align-self: center;
  white-space: nowrap;
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: .2rem;
}
.cal__add:hover { border-bottom-color: var(--ink); }
.cal__add:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* "Details" is the most-tapped thing on the calendar and it was a 24px target —
   under half what a thumb needs. The hit area is grown with a pseudo-element
   rather than with padding so nothing moves: the link looks and sits exactly as
   it did at every width, it is simply easier to hit. Nothing around it is
   clickable, so the extra area costs its neighbours nothing. */
.cal__add { position: relative; }
.cal__add::after {
  position: absolute;
  inset: -11px -10px;
  content: "";
}

/* A held event stays legible — it is reference, not an offer. */
.cal__row[data-past] .cal__date { opacity: .5; }

.cal__empty { padding: 2.5rem 0; font-size: 1.05rem; }
/* The button that releases the next few events. Quiet and centred: a way of
   going on reading, not a call to action. */
.cal__more { margin: 2rem 0 0; text-align: center; }
.cal__more[hidden] { display: none; }
.cal__empty[hidden] { display: none; }

.events__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  margin-top: 2.25rem;
}

.events__actions { display: flex; flex-wrap: wrap; gap: .75rem; }

.events__subscribe { margin: 0; font-size: .875rem; opacity: .75; }
.events__subscribe a { text-underline-offset: 3px; }
.events__subscribe span { margin: 0 .45rem; opacity: .5; }

/* ── Event detail (/events/<slug>/) ───────────────────────────────────────
   The practical facts sit in a rail beside the copy: when, where, who, and the
   one thing to do. */
.mhero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: min(70svh, 640px);
  padding: 10rem 0 3.5rem;
  color: var(--sand);
  overflow: hidden;
}
/* Not pinned to the viewport. `fixed` scales the photograph to cover the whole
   window and then shows the hero's slice of it, which for a hero shorter than
   the window is always the top — and these photographs are wide skies over a
   low horizon, so every event opened on cloud. Scrolling with the page lets
   `cover` fit the hero's own box, and the position below can reach the land. */
.mhero__bg {
  position: absolute;
  inset: 0;
  background-position: center 72%;
  background-size: cover;
  background-repeat: no-repeat;
}
.mhero__bg::after {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg, rgba(20, 22, 26, .52) 0%, rgba(20, 22, 26, .30) 35%, rgba(20, 22, 26, .74) 100%);
  content: "";
}
.mhero__inner { position: relative; }
.mhero__eyebrow {
  margin: 0 0 1rem;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  opacity: .85;
}
.mhero h1 {
  max-width: 20ch;
  font-size: clamp(1.875rem, 1.2rem + 2.2vw, 3rem);
  font-weight: 500;
  line-height: 1.15;
  margin-bottom: 1rem;
}
.mhero__lead {
  margin: 0;
  max-width: 52ch;
  font-size: clamp(1.0625rem, 1rem + .4vw, 1.25rem);
  line-height: 1.5;
}
.mhero__crumb { margin: 0 0 1rem; font-size: .8125rem; opacity: .85; }
.mhero__crumb a { text-underline-offset: 3px; }
.mhero__crumb span { margin: 0 .4rem; }

/* Country is named on the photograph rather than left anonymous. */
.mhero__credit {
  position: absolute;
  right: max(1.5rem, calc((100% - var(--shell)) / 2));
  bottom: 1.25rem;
  z-index: 1;
  margin: 0;
  padding: .5rem 1rem;
  background: rgba(28, 30, 34, .62);
  font-size: .75rem;
  letter-spacing: .04em;
}

/* The calendar's own hero. Mer, in the eastern Torres Strait — Eddie Koiki
   Mabo's Country, and the Country the Mabo case was fought over. On a calendar
   owned jointly with the Mabo Centre it is the one photograph that means
   something rather than merely looking well.

   The horizon sits a little above the middle of the frame, and the open sand
   below it is what the eyebrow, the title and the lead are set on. */
/* An event with no photograph of its own, held online or in a state the
   calendar carries no picture of. It opens on the calendar's own colour rather
   than on somebody else's Country, and gives the space back to the title. */
.mhero--plain {
  min-height: 0;
  padding: calc(var(--headroom) + clamp(2rem, 1.5rem + 2vw, 3.5rem)) 0 clamp(2.5rem, 2rem + 2vw, 3.5rem);
  background: var(--deep);
}
.mhero--plain .mhero__crumb a { text-decoration: underline; }

.mhero--home .mhero__bg { background-position: center 46%; }
/* A softer scrim than the default. This photograph is already low-key — a
   clouded sunrise over water — and the standard veil takes the last of the
   colour out of it. The weight it does carry is at the foot, under the type. */
.mhero--home .mhero__bg::after {
  background: linear-gradient(
    180deg, rgba(20, 22, 26, .34) 0%, rgba(20, 22, 26, .18) 38%, rgba(20, 22, 26, .68) 100%);
}
.mhero--home h1 { max-width: 18ch; margin-bottom: 1.25rem; }

/* Written from the visitor's clock rather than typed into the page, because a
   status typed into the page goes stale. */
.evd__status {
  display: inline-block;
  margin: 0 0 1rem;
  padding: .35rem .75rem;
  background: rgba(241, 234, 232, .16);
  border: 1px solid rgba(241, 234, 232, .5);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.evd__status[hidden] { display: none; }
.evd__dates { margin: 0; font-size: clamp(1rem, .95rem + .3vw, 1.125rem); opacity: .9; }

.evd__grid {
  display: grid;
  grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4.5rem);
  padding: clamp(2.5rem, 2rem + 2vw, 4rem) 0 clamp(3rem, 2.5rem + 2vw, 4.5rem);
}
.evd__rail { position: sticky; top: 6.5rem; align-self: start; }
.evd__detail { margin: 0 0 1.75rem; }
.evd__row { padding: .85rem 0; border-top: 1px solid var(--rule); }
.evd__row:last-child { border-bottom: 1px solid var(--rule); }
.evd__row dt {
  margin-bottom: .3rem;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.evd__row dd { margin: 0; font-size: .9375rem; line-height: 1.5; }
/* The host badge again, but alone in a rail rather than first in a row of
   metadata, so it drops the divider that separates it from what follows. */
.evd__row dd .cal__host {
  display: inline-block;
  padding-right: 0;
  border-right: 0;
  font-size: .75rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.evd__missing { color: color-mix(in srgb, var(--ink) 45%, transparent); font-style: italic; }

/* The zone after a time. Quieter than the time, since the time is what someone
   is looking for — but present, since on a calendar spanning three hours of
   longitude a time without a zone is a guess. */
.evd__zone {
  margin-left: .2em;
  font-size: .8125em;
  letter-spacing: .04em;
  color: color-mix(in srgb, var(--ink) 60%, transparent);
}
.evd__rail-cta { margin: 0 0 1.75rem; }
.evd__rail-cta[hidden] { display: none; }
/* Shown at its own shape, never cropped. A poster is a document — the crop that
   suits a hero photograph is the crop that cuts the times off a flyer.

   Under the description, and held to a width a poster is actually read at.
   Given the full column it would tower over the prose it belongs to; a flyer at
   about the width of a sheet of paper on a desk reads as one. */
.evd__poster {
  margin: 2.5rem 0 0;
  padding-top: 2.5rem;
  border-top: 1px solid var(--rule);
  max-width: 30rem;
}
.evd__poster a { display: block; }
.evd__poster img {
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  background: var(--field);
}
.evd__poster a:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.evd__poster figcaption {
  margin-top: .5rem;
  font-size: .75rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

.evd__back { margin: 0; font-size: .9375rem; }
.evd__back a { text-underline-offset: 3px; }

.evd__col { max-width: 42rem; font-size: 1.0625rem; line-height: 1.75; }
.evd__col > * + * { margin-top: 1.15em; }
.evd__col h2 {
  margin-top: 2rem;
  font-size: clamp(1.25rem, 1.1rem + .6vw, 1.5rem);
  font-weight: 500;
  line-height: 1.3;
}
.evd__col h2:first-child { margin-top: 0; }
.evd__col a { text-underline-offset: 3px; overflow-wrap: anywhere; }

/* ── The Events Calendar's own markup ─────────────────────────────────────
   The plugin writes the body of an event. The theme does not override the
   plugin's templates — that ties a theme to a plugin version — so its output
   is brought into the design system here instead. */
.tribe-events-single p { margin-bottom: 1.15em; }
.tribe-events-single h2,
.tribe-events-single h3 { margin: 2rem 0 .75rem; line-height: 1.3; }
.tribe-events-single ul,
.tribe-events-single ol { padding-left: 1.15rem; margin-bottom: 1.15em; }
.tribe-events-single li + li { margin-top: .4em; }
.tribe-events-single img { max-width: 100%; height: auto; }
.tribe-events-single a { text-underline-offset: 3px; overflow-wrap: anywhere; }

/* The plugin repeats the date, venue and organiser under the content. The rail
   already says all of it, in the design system's own type. */
.tribe-events-single .tribe-events-event-meta,
.tribe-events-single .tribe-events-schedule,
.tribe-events-single .tribe-events-sub-nav { display: none; }

/* ── The submission form ──────────────────────────────────────────────────
   One column of plain questions. No wizard, no progress bar: the people using
   this add one event occasionally, so there is nothing to learn and nothing
   worth breaking into steps.

   Errors sit under the field they belong to and the field is marked. A summary
   at the top saying "please correct the errors below" without saying which is
   the reason people abandon forms. */
.sub { padding: 0 0 clamp(3.5rem, 3rem + 2vw, 5.5rem); }
.sub__form { max-width: 44rem; }

.sub__alert {
  margin: 0 0 2rem;
  padding: 1rem 1.25rem;
  border-left: 3px solid var(--ochre);
  background: color-mix(in srgb, var(--ochre) 12%, transparent);
  font-size: .95rem;
  font-weight: 500;
}

/* The floating version, for errors that are marked on fields further down.
   Pinned to the foot of the window so it is readable from anywhere in a form
   that is taller than the screen — which is the whole problem with putting it
   at the top. Solid rather than tinted, because it now sits over the form
   rather than in the flow of it. */
.sub__alert--float {
  position: fixed;
  z-index: 200;
  left: 50%;
  bottom: clamp(1rem, 3vh, 2rem);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 1rem;
  width: max-content;
  max-width: min(100% - 2rem, 34rem);
  margin: 0;
  padding: .85rem .85rem .85rem 1.15rem;
  border: 0;
  border-left: 3px solid var(--ochre);
  border-radius: 12px;
  background: var(--deep);
  color: var(--sand);
  box-shadow: 0 6px 28px rgba(20, 22, 26, .3);
  animation: sub-alert-in .22s ease-out;

  /* Solid to look at, transparent to touch. Reserving space below the form
     stops the bar covering the send button at rest, but there are still scroll
     positions where the button sits behind it — and a tap that lands on a
     notice and silently does nothing is the most confusing kind of dead press.
     Its own two controls take pointer events back. */
  pointer-events: none;
}
.sub__alert--float[hidden] { display: none; }
.sub__alert__go,
.sub__alert__close { pointer-events: auto; }

.sub__alert__text { margin: 0; flex: 1; font-size: .9375rem; font-weight: 500; }

.sub__alert__go {
  flex: none;
  padding: .45rem .9rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--ink);
  font-size: .875rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}
.sub__alert__go:hover { filter: brightness(1.07); }
.sub__alert__go:focus-visible { outline: 3px solid var(--sand); outline-offset: 2px; }

.sub__alert__close {
  flex: none;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  opacity: .7;
}
.sub__alert__close:hover { opacity: 1; background: rgba(255, 255, 255, .12); }
.sub__alert__close:focus-visible { outline: 3px solid var(--sand); outline-offset: 2px; }

@keyframes sub-alert-in {
  from { opacity: 0; transform: translate(-50%, .6rem); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* A field the floating message has just sent someone to. It marks where they
   landed, which a scroll on its own does not. */
.fld.is-found > .fld__in,
.fld.is-found .fld__file { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 55%, transparent); }

/* The message is pinned to the foot of the window, so without this it sits over
   whatever is at the bottom of the form — including "Send for approval", which
   is the one control it is talking about. The space is reserved only in the
   error state, so the form as normally seen is unchanged. */
.sub--alerted { padding-bottom: 7rem; }

@media (max-width: 640px) {
  .sub__alert--float {
    left: 1rem;
    right: 1rem;
    width: auto;
    max-width: none;
    transform: none;
    gap: .6rem;
    padding-left: 1rem;
  }
  .sub__alert__text { font-size: .875rem; }

  /* Both were under the size a thumb reliably hits. Only on small screens —
     at desktop sizes they are pointer targets and sized for the bar. */
  .sub__alert__go { min-height: 44px; display: inline-flex; align-items: center; }
  .sub__alert__close { width: 44px; height: 44px; }

  .sub--alerted { padding-bottom: 8.5rem; }
  @keyframes sub-alert-in {
    from { opacity: 0; transform: translateY(.6rem); }
    to   { opacity: 1; transform: translateY(0); }
  }
}

/* The rule between sections is the bottom edge of the one above, never the top
   edge of the one below. A legend sits *in* its fieldset's top border and
   notches it, so a border-top reads as "WHERE————" with the line running off to
   the right; nothing sits in the bottom edge, so it closes cleanly. */
.sub__set {
  border: 0;
  border-bottom: 1px solid var(--rule);
  margin: 0 0 2.5rem;
  padding: 0 0 2.5rem;
}
.sub__set:last-of-type { border-bottom: 0; padding-bottom: 0; }
.sub__legend {
  padding: 0;
  margin-bottom: 1.5rem;
  font-size: .6875rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.sub__note {
  margin: 0 0 1.25rem;
  font-size: .8125rem;
  color: color-mix(in srgb, var(--ink) 65%, transparent);
}

/* The header is fixed, so anything jumped to by an anchor arrives underneath
   it. That is how the floating message's "Show me" behaves with no script, and
   how any link into a field behaves — the field scrolls to the very top of the
   window and the dark bar sits over it. */
.fld { margin: 0 0 1.5rem; display: flex; flex-direction: column; gap: .35rem; scroll-margin-top: calc(var(--headroom) + 1rem); }
.fld__label { font-size: .9375rem; font-weight: 600; }
.fld__hint { font-size: .8125rem; color: color-mix(in srgb, var(--ink) 62%, transparent); }
.fld__in {
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--field);
  border: 1px solid var(--rule);
  border-radius: 10px;
  padding: .7rem .85rem;
  width: 100%;
}
.fld__in--area { resize: vertical; min-height: 8rem; line-height: 1.5; }
.fld__in--sel {
  appearance: none;
  cursor: pointer;
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%232b2e34' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .9rem center;
  background-size: 12px 8px;
}
.fld__in:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* The one control on the site a browser will not let us restyle, so it is given
   room and a rule rather than a fight. */
.fld__file {
  font: inherit;
  font-size: .9375rem;
  padding: .7rem .85rem;
  border: 1px dashed var(--rule);
  border-radius: 10px;
  background: var(--field);
  width: 100%;
}
.fld__file::file-selector-button {
  font: inherit;
  font-size: .8125rem;
  font-weight: 500;
  letter-spacing: .04em;
  margin-right: .85rem;
  padding: .45rem .9rem;
  border: 0;
  border-radius: 8px;
  background: var(--accent);
  color: var(--ink);
  cursor: pointer;
}
.fld__file:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.fld.is-bad .fld__file { border-color: #a4442e; border-style: solid; }

.fld.is-bad .fld__in { border-color: #a4442e; border-width: 2px; }
.fld__err { font-size: .8125rem; font-weight: 600; color: #a4442e; }

/* Aligned on the fields, not on the labels: one half of a pair usually carries
   a hint line and the other does not, and two inputs a hint's height apart
   reads as a mistake. */
.fld__row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.25rem; align-items: end; margin-bottom: 1.5rem; }
/* The gap belongs to the row, not to the fields in it: a field's own bottom
   margin is part of what `align-items: end` measures, so leaving it there
   offsets the very inputs this is aligning. */
.fld__row > .fld { margin-bottom: 0; }

.fld--check { margin-bottom: 1.75rem; }
.fld__check { display: flex; align-items: center; gap: .6rem; cursor: pointer; font-size: .9375rem; }
.fld__check input { width: 1.1rem; height: 1.1rem; accent-color: var(--olive); }

/* Off-screen rather than display:none — a bot that skips hidden fields skips
   the trap, which defeats the point of setting it. */
.sub__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.sub__actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
  margin: 0;
  padding-top: .5rem;
}
.sub__actions .sub__note { margin: 0; flex: 1 1 14rem; }

/* ── The embeddable fragment (/calendar-embed/) ───────────────────────────
   What nntc.com.au and mabocentre.com actually show. It sits inside an iframe
   on someone else's page, so it carries no page furniture of its own and no
   background — the host page's background shows through, which is what stops a
   framed calendar reading as a foreign box dropped onto the page.

   There is no gutter at all, because the frame is already inside the host
   page's own margins. Any gutter here adds to theirs, and a row indented from
   the heading above it is the tell that the calendar is a foreign box. The host
   sizes the iframe; the rows line up with its own text. */
body.is-embed { background: transparent; margin: 0; }
body.is-embed .shell { width: 100%; }

.emb { padding: 0; }
.emb__empty {
  margin: 0;
  padding: 2rem 1rem;
  font-size: .95rem;
  color: var(--ink);
  opacity: .75;
}
.emb__empty a { color: inherit; }

/* Nothing scheduled. Flush with the page's own measure rather than indented,
   and only as tall as it needs to be: the host page frames this and resizes to
   whatever height it reports, so every unused pixel here is a hole there. */
.emb__none { padding: .25rem 0 1.75rem; max-width: 46ch; }
.emb__none-lead { margin: 0 0 .5rem; font-size: 1.125rem; font-weight: 500; color: var(--ink); }
.emb__none-sub { margin: 0; font-size: .9375rem; line-height: 1.55;
  color: color-mix(in srgb, var(--ink) 65%, transparent); }

/* The listing's own ground and vertical padding belong to the host page's
   section, not to the frame. Framed, the section starts and ends exactly where
   the design says it does — filters at the top, foot at the bottom. */
.is-embed .events { padding: 0; background: transparent; }

/* ── Acknowledgement of Country ─────────────────────────────────────────────
   NNTC sets this panel in its olive. The Mabo Centre sets its own on aubergine
   and — the part worth taking — puts the cultural warning first, with a heading,
   as the thing you meet before anything else rather than a footnote under the
   acknowledgement.

   Here it is the deep violet the header wears, so the panel belongs to the
   calendar rather than to one of its owners, and the warning is given a heading
   of its own and full weight. The wording of both is the organisations' to
   agree; nothing here should invent it. */
.ack {
  background: var(--deep);
  color: var(--sand);
}
.ack__inner {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 0;
  align-items: stretch;
}
.ack__media { margin: 0; display: grid; }
.ack__media img {
  width: 100%;
  height: 100%;
  min-height: 20rem;
  object-fit: cover;
  object-position: center 40%;
}
.ack__text {
  padding: clamp(2.5rem, 2rem + 2vw, 4rem) max(1.5rem, calc((100% - var(--shell)) / 2)) clamp(2.5rem, 2rem + 2vw, 4rem) clamp(2rem, 4.5vw, 4.5rem);
  max-width: 60ch;
}
.ack__head {
  margin-bottom: 1.25rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.ack__text p { font-size: 1.125rem; line-height: 1.55; }

.ack__block + .ack__block {
  margin-top: 1.75rem;
  padding-top: 1.75rem;
  border-top: 1px solid rgba(255, 255, 255, .22);
}
/* Not dimmed and not in the small print. A cultural warning that is quieter
   than the text above it is a warning arriving after it was needed. */
.ack__warning p { font-size: 1.0625rem; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
.site-footer > .shell { padding: 2rem 0 2.5rem; }
.site-footer__copy {
  margin: 0;
  font-size: .75rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}

/* ── Responsive ───────────────────────────────────────────────────────────── */
/* The listing's own breakpoint, from the NNTC sheet, so a row breaks the same
   way in the frame as it does natively. */
@media (max-width: 760px) {
  .events { padding: 3rem 0 3rem; }
  .filt { flex: 1 1 12rem; }
  .filt__select { min-width: 0; width: 100%; }
  .calseg { flex: 1 1 100%; }
  .calseg__btn { flex: 1; }

  /* Date moves above the title rather than beside it: at this width a fixed
     date column costs more than it earns. */
  .cal__row {
    grid-template-columns: 1fr;
    gap: .75rem;
    padding: 1.35rem 0;
  }
  .cal__date { flex-direction: row; align-items: baseline; gap: .5rem; }
  .cal__mon { margin-top: 0; }
  .cal__day { font-size: 1.75rem; }
  .cal__range { font-size: 1.05rem; }
  .cal__add { align-self: start; justify-self: start; }
  .events__foot { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 900px) {
  .ack__inner { grid-template-columns: minmax(0, 1fr); }
  .ack__media img { height: auto; min-height: 0; aspect-ratio: 21 / 9; }
  .ack__text { padding: 2.5rem 1.5rem 3rem; max-width: none; }
  .evd__grid { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .evd__rail { position: static; }
  .evd__col { max-width: none; font-size: 1rem; }
}

@media (max-width: 640px) {
  .shell { width: min(100% - 2rem, var(--shell)); }
  .site-header__rule { display: none; }
  .site-header__inner { justify-content: space-between; gap: 1rem; }
  .logo__word { font-size: .6875rem; letter-spacing: .08em; }
  .nav__contact { padding: .7rem .9rem; font-size: .75rem; }

  /* Room under the lead for the credit plate, which stays pinned to the foot
     of the photograph rather than shrinking into the text. */
  .mhero { min-height: 0; padding: 7rem 0 4.25rem; }
  .mhero__credit { right: 1rem; font-size: .6875rem; padding: .4rem .7rem; }
  .fld__row { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
