/* schoolcalendars.co.za
   Mobile first. The desktop layout starts at 980px.

   The layout rule the whole sheet serves: on a phone the next holiday fills
   the first screen on its own, and everything that is useful but is not the
   answer sits behind a disclosure. */

:root {
  --ground: #FBF7F1;
  --panel: #F0EAE0;
  --panel-2: #F5F0E8;
  --line: #E4DBCC;
  --ink: #2E2823;
  --ink-2: #5C544C;
  --ink-3: #8A8177;
  --ink-4: #A0968A;

  /* Two accents, same chroma and lightness, different hue.
     Orange is an end-of-term holiday. Blue is a half-term break. */
  --holiday: #C9501B;
  --holiday-deep: #A03E12;
  --half: #3A63C9;
  --half-deep: #28489D;
  /* Green is a term: the school days between two breaks. It is deliberately
     quieter than the two break accents, because a break is the answer. */
  --term: #2E7D5B;
  --term-deep: #235F45;
  --term-tint: #E7F0EA;
  --on-accent: #FFF6EE;

  --display: "Bricolage Grotesque", "Helvetica Neue", Helvetica, sans-serif;
  --body: "Public Sans", "Helvetica Neue", Helvetica, sans-serif;
  --radius: 4px;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.5;
}

h1, h2, h3 { font-family: var(--display); letter-spacing: -0.025em; margin: 0; line-height: 1.08; }

a { color: var(--holiday); text-decoration: none; }
a:hover { color: var(--holiday-deep); text-decoration: underline; }

img { max-width: 100%; display: block; }

.tnum { font-variant-numeric: tabular-nums; }
.display { font-family: var(--display); }
.wrap { max-width: 1240px; margin: 0 auto; padding: 0 20px; }
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }

/* ---------- buttons: one action per screen ---------- */

.btn {
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  background: var(--ink);
  color: var(--ground);
}
.btn:hover { background: #453D35; }
/* The hard shadow gives the button an edge to press, which is what a flat
   rectangle is missing. Pressing takes the shadow away and moves the face
   down by the same amount, so the button never changes size. */
.btn--primary {
  background: var(--holiday);
  color: var(--on-accent);
  font-size: 17px;
  box-shadow: 0 3px 0 var(--holiday-deep);
  transition: transform 90ms ease, box-shadow 90ms ease, background 120ms ease;
}
.btn--primary:hover { background: var(--holiday-deep); box-shadow: 0 3px 0 #7E2F0C; }
.btn--primary:active { transform: translateY(3px); box-shadow: 0 0 0 var(--holiday-deep); }
.btn--block { width: 100%; min-height: 56px; justify-content: space-between; padding: 0 20px; }
.btn__label { text-align: left; }
.btn__arrow { font-size: 20px; line-height: 1; transition: transform 140ms ease; }
.btn--block:hover .btn__arrow { transform: translateX(4px); }
.btn:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.btn--onAccent { background: var(--on-accent); color: var(--holiday); }
.btn--onAccent:hover { background: #fff; }
.btn--onHalf { background: #F2F5FE; color: var(--half); }
.btn--quiet { background: transparent; color: var(--ink); border: 1.5px solid var(--line); font-weight: 600; }
.btn--quiet:hover { background: var(--panel); }
.btn[disabled] { opacity: 0.45; cursor: default; }

/* ---------- site header ---------- */

.siteheader {
  border-bottom: 1px solid var(--line);
  background: var(--ground);
  position: sticky;
  top: 0;
  z-index: 5;
}
.siteheader .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 56px;
}
.wordmark {
  font-size: 12px; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--holiday);
}
/* The nav is the desktop way between calendars. A phone has the chip and
   "Change" instead, which say the same thing in the width available. */
.sitenav { display: none; }
.navlink {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 12px; border: 0; background: transparent; border-radius: 3px;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-2);
  cursor: pointer; white-space: nowrap;
}
.navlink:hover { background: var(--panel); color: var(--ink); text-decoration: none; }
.navlink--on { color: var(--holiday); box-shadow: inset 0 -2px 0 var(--holiday); border-radius: 3px 3px 0 0; }
.navlink--quiet { color: var(--ink-3); }
.navlink:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.variation { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.variation a { display: inline-flex; align-items: center; min-height: 44px; }
.siteheader .wordmark { display: inline-flex; align-items: center; gap: 7px; min-height: 44px; }
.wordmark__icon { flex-shrink: 0; }
.chip {
  padding: 5px 10px; border-radius: 3px; background: var(--panel);
  font-weight: 600; font-size: 12px; white-space: nowrap;
}
/* On a narrow screen the wordmark yields space to the variation, because the
   variation is the thing a returning parent checks. */
@media (max-width: 420px) {
  .wordmark { font-size: 10px; letter-spacing: 0.06em; }
  .chip { font-size: 11px; padding: 4px 8px; }
  .variation { font-size: 12px; gap: 6px; }
}

/* ---------- the answer at the top ---------- */

/* The photograph is the hero, full bleed behind the answer, with a scrim so
   the text sitting on it stays readable. The same treatment for every break:
   no colour-coded background competing with the picture. */
.hero {
  position: relative;
  color: var(--on-accent);
  background: var(--ink-2);
  padding: 32px 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.hero--empty { background: linear-gradient(152deg, #6E655B 0%, var(--ink-2) 55%, #443D36 100%); }

.hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 58%;
}
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(46,40,35,0.90) 0%, rgba(46,40,35,0.66) 38%,
    rgba(46,40,35,0.10) 72%, rgba(46,40,35,0) 100%);
}
.hero__content { position: relative; z-index: 1; }
.hero__body { display: flex; flex-direction: column; gap: 14px; min-width: 0; max-width: 620px; }
.hero .eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; opacity: 0.85;
}
.hero .count { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.hero .count b {
  font-family: var(--display); font-size: clamp(64px, 19vw, 104px);
  font-weight: 800; line-height: 0.82; letter-spacing: -0.045em;
}
.hero .count span { font-family: var(--display); font-size: clamp(22px, 6vw, 30px); font-weight: 600; }
.hero h1 { font-size: clamp(25px, 7vw, 34px); font-weight: 800; }
.hero .dates { font-size: clamp(16px, 4.4vw, 19px); font-weight: 700; }
.hero .rule { height: 1px; background: rgba(255,255,255,0.32); }
.hero .lines { display: flex; flex-direction: column; gap: 4px; font-size: 15px; }
.halfday {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; padding: 4px 7px; border-radius: 3px;
  background: rgba(255,255,255,0.22); vertical-align: middle; margin-left: 8px;
}

/* ---------- period cards ---------- */

.section-head { display: flex; flex-direction: column; gap: 4px; margin: 28px 0 14px; }
.section-head h2 { font-size: clamp(24px, 6vw, 30px); font-weight: 800; }
.section-head .sub { font-size: 13px; color: var(--ink-3); }

.periods { display: flex; flex-direction: column; gap: 10px; }

.period {
  /* width:auto, not 100%: the inset half-term card adds a left margin and a
     percentage width would push the column sideways. */
  border: 0; display: block; width: auto; text-align: left; font: inherit;
  padding: 16px 18px; border-radius: var(--radius);
  background: var(--panel); color: var(--ink);
}
.period--holiday { background: var(--holiday); color: var(--on-accent); cursor: pointer; }
.period--term { background: var(--term-tint); border-left: 6px solid var(--term); color: var(--term-deep); }
.period--term .period__kicker, .period--term .period__dates, .period--term .period__len { color: inherit; opacity: 0.8; }
/* Inset, so a term reads as one span with its half-term nested inside it.
   The width is reduced explicitly: a stretched flex item plus a margin
   overflows the column. */
.period--half { background: var(--half); color: #F2F5FE; cursor: pointer; margin-left: 24px; width: calc(100% - 24px); }
.period__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.period__kicker {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-3);
}
.period--holiday .period__kicker, .period--half .period__kicker { color: inherit; opacity: 0.82; }
.period__name { font-family: var(--display); font-size: 18px; font-weight: 800; letter-spacing: -0.02em; }
.period--holiday .period__name, .period--half .period__name { font-size: 23px; }
.period__dates { font-size: 14px; font-weight: 600; color: var(--ink-2); }
.period--holiday .period__dates, .period--half .period__dates { color: inherit; font-size: 16px; }
.period__len { flex-shrink: 0; font-family: var(--display); font-weight: 800; font-size: 14px; color: var(--ink-3); }
.period--holiday .period__len, .period--half .period__len { color: inherit; font-size: 16px; }

.phchips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.phchip {
  font-size: 12px; padding: 4px 8px; border-radius: 3px;
  background: var(--ground); border: 1px solid var(--line); color: var(--ink-2);
}

.period__more {
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,0.35);
  display: flex; flex-direction: column; gap: 12px;
}
.period__more .lines { display: flex; flex-direction: column; gap: 3px; font-size: 14px; }

.gapcard {
  padding: 16px 18px; border-radius: var(--radius);
  border: 1.5px dashed var(--ink-4); background: var(--panel-2);
  display: flex; flex-direction: column; gap: 6px;
}
.gapcard b { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-4); }
.gapcard p { margin: 0; font-size: 14px; color: var(--ink-2); }

/* ---------- reserved advertising positions ---------- */

/* Empty at launch, and the space is held from day one so that switching
   advertising on later moves nothing on the page. */
.adslot {
  border-radius: 3px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; text-align: center; padding: 12px 16px;
  color: var(--ink-4); font-size: 12px;
}
.adslot:not(:empty) { border: 1.5px dashed var(--ink-4); }
.adslot b { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.adslot--1 { min-height: 104px; margin-top: 16px; }
.adslot--2 { min-height: 76px; border-color: rgba(255,255,255,0.5); color: rgba(255,255,255,0.78); }
.adslot--3 { min-height: 84px; margin: 16px 0 0; }

/* ---------- provenance ---------- */

.provenance {
  margin: 0; padding: 18px; background: var(--panel);
  border-radius: var(--radius); display: flex; flex-direction: column; gap: 12px;
}
.provenance h3 { font-size: 15px; font-weight: 800; }
.provenance p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.provenance .verified { font-size: 13px; font-weight: 700; color: var(--ink); }
.provenance hr { border: 0; height: 1px; background: #DDD3C4; margin: 0; }

/* ---------- the year grid ---------- */

.gridwrap { overflow-x: auto; padding-bottom: 6px; }
.yeargrid { display: flex; flex-direction: column; gap: 3px; min-width: 620px; }
.yeargrid .head, .yeargrid .monthrow { display: flex; align-items: center; gap: 2px; }
.yeargrid .head { padding-left: 92px; }
.yeargrid .head i {
  width: 17px; text-align: center; font-style: normal;
  font-size: 10px; font-weight: 600; color: var(--ink-4);
}
.yeargrid .mname {
  width: 92px; flex-shrink: 0; font-family: var(--display);
  font-size: 12px; font-weight: 700;
}
.yeargrid .cell { width: 17px; height: 19px; border-radius: 2px; flex-shrink: 0; }
/* Term days carry the term colour, so the grid and the term blocks agree. */
.cell--term { background: var(--term-tint); }
.cell--weekend { background: #F1F6F2; }
.cell--holiday { background: var(--holiday); }
.cell--half { background: var(--half); }
.cell--ph { background: var(--ink); }
.cell--unknown { background: repeating-linear-gradient(135deg, #F5F0E8 0 4px, #EAE2D5 4px 8px); }
.cell--today { box-shadow: inset 0 0 0 2px var(--ground), inset 0 0 0 4px var(--ink); }

.legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 12px; color: var(--ink-2); margin: 12px 0; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 13px; height: 13px; border-radius: 2px; font-style: normal; }

/* Public holidays change the length of a break, so they get a named panel. */
.phpanel {
  margin-top: 14px; padding: 16px 18px; background: var(--ink); color: var(--ground);
  border-radius: var(--radius); display: flex; flex-direction: column; gap: 10px;
}
.phpanel h3 { font-size: 16px; font-weight: 800; }
.phpanel .items { display: flex; flex-wrap: wrap; gap: 8px; }
.phpanel .item {
  display: flex; flex-direction: column; gap: 1px; padding: 9px 13px;
  border-radius: 3px; background: rgba(251,247,241,0.12);
}
.phpanel .item b { font-size: 15px; font-weight: 700; }
.phpanel .item span { font-size: 12px; opacity: 0.78; }
.phpanel .foot { font-size: 12px; opacity: 0.7; }

/* ---------- chooser ---------- */

/* A full-bleed photograph opens the home page, with the next break in each
   calendar as pills over it. Below it, the question and the three
   calendars, which stack on a phone and stand side by side from 980px. */
.chooser-head { display: flex; flex-direction: column; gap: 12px; }
.chooser-head h1 { font-size: clamp(32px, 9vw, 44px); font-weight: 800; }

.herotop {
  position: relative; overflow: hidden; min-height: 280px;
  display: flex; align-items: flex-end;
  border-bottom: 1px solid var(--line);
}
.herotop__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 55%;
}
.herotop__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(46,40,35,0) 20%, rgba(46,40,35,0.82) 100%);
}
.herotop__content {
  position: relative; z-index: 1; width: 100%;
  padding: 22px 20px 26px;
  display: flex; flex-direction: column; gap: 12px;
  color: var(--on-accent);
}
.herotop .eyebrow {
  margin: 0; font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; opacity: 0.85;
}
.herotop__title {
  margin: 0; font-family: var(--display); font-weight: 800;
  font-size: clamp(24px, 7vw, 32px); line-height: 1.08; max-width: 620px;
}

/* The answer, before the choice. Each row is the next break in one calendar,
   restyled as a glass pill over the photo, so the page is useful even to a
   parent who has not chosen yet. On a phone the pills stack, so every
   calendar's answer is in view without a sideways scroll. */
.herotop .peek {
  margin: 4px 0 0; padding: 0; border: 0; background: transparent;
  display: flex; flex-direction: column; gap: 8px;
}
/* The "next break" label still gives the pills context to a screen reader,
   just not to the eye, which already reads it per pill. */
.herotop .peek__title {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.herotop .peek__row {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-top: 0; border-radius: var(--radius);
  background: rgba(251,247,241,0.14); border: 1px solid rgba(251,247,241,0.3);
  backdrop-filter: blur(6px); color: var(--on-accent);
}
.herotop .peek__row:hover {
  text-decoration: none; color: var(--on-accent);
  background: rgba(251,247,241,0.22);
}
.herotop .peek__dot {
  flex-shrink: 0; width: 10px; height: 10px; border-radius: 2px; background: var(--holiday);
}
.herotop .peek__dot--half { background: var(--half); }
.herotop .peek__body { display: flex; flex-direction: column; min-width: 0; flex-grow: 1; }
.herotop .peek__where {
  font-size: 11px; color: rgba(255,246,238,0.75);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.herotop .peek__what {
  font-family: var(--display); font-size: 16px; font-weight: 800;
  letter-spacing: -0.02em; color: var(--on-accent);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.herotop .peek__when { font-size: 13px; font-weight: 700; white-space: nowrap; color: rgba(255,246,238,0.92); }

.chooser { padding-top: 28px; padding-bottom: 8px; }
.chooser-actions { display: flex; flex-direction: column; gap: 12px; }

.options { display: flex; flex-direction: column; gap: 12px; }

/* A choice card, not a radio row. The colour rail on the left is the whole
   selected state seen from arm's length; the tick confirms it up close. */
.option {
  position: relative;
  display: flex; gap: 14px; align-items: flex-start; width: 100%; text-align: left;
  font: inherit; padding: 18px 18px 18px 22px; border-radius: var(--radius);
  background: #fff; border: 1.5px solid var(--line); cursor: pointer;
  box-shadow: 0 1px 0 rgba(46,40,35,0.05);
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}
.option::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--line);
  transition: background 120ms ease;
}
.option:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(46,40,35,0.10); border-color: #D3C6B2; }
.option:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
.option[aria-checked="true"] {
  border-color: var(--holiday);
  box-shadow: 0 3px 0 var(--holiday-deep), 0 8px 18px rgba(201,80,27,0.16);
}
.option[aria-checked="true"]::before { background: var(--holiday); }

.option__body { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex-grow: 1; }
.option__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.option .name { font-family: var(--display); font-size: 20px; font-weight: 800; letter-spacing: -0.02em; }
.option .region { font-size: 14px; color: var(--ink-2); }
.option .badge {
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 999px;
  background: var(--term-tint); color: var(--term-deep); white-space: nowrap;
}
.option .badge--soon { background: var(--panel); color: var(--ink-3); }

/* The tick is drawn with borders so the card carries no image weight. */
.option .ring {
  position: relative; flex-shrink: 0; width: 26px; height: 26px; margin-top: 2px; border-radius: 50%;
  border: 2px solid #C4B9A8; background: var(--ground);
  transition: background 120ms ease, border-color 120ms ease;
}
.option[aria-checked="true"] .ring { border-color: var(--holiday); background: var(--holiday); }
.option[aria-checked="true"] .ring::after {
  content: "";
  position: absolute; left: 8px; top: 4px;
  width: 6px; height: 11px;
  border-right: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
  transform: rotate(42deg);
}

/* ---------- holiday detail ---------- */

.stats { display: flex; gap: 22px; flex-wrap: wrap; padding-top: 4px; }
.stats div { display: flex; flex-direction: column; gap: 2px; }
.stats b { font-family: var(--display); font-size: 28px; font-weight: 800; letter-spacing: -0.03em; }
.stats span { font-size: 12px; opacity: 0.85; }

.months { display: flex; flex-direction: column; gap: 18px; margin-top: 14px; }
.month h3 { font-size: 15px; font-weight: 800; margin-bottom: 8px; }
.monthgrid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; max-width: 380px; }
.monthgrid .h {
  text-align: center; font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-4);
}
.monthgrid .d {
  height: 36px; display: flex; align-items: center; justify-content: center;
  border-radius: 3px; font-size: 13px; font-variant-numeric: tabular-nums;
  background: #EDE6DA; color: var(--ink-2);
}
.monthgrid .d.weekend { background: var(--panel-2); color: var(--ink-4); }
.monthgrid .d.inbreak { background: var(--holiday); color: var(--on-accent); font-weight: 700; }
.monthgrid .d.inbreak.half { background: var(--half); }
.monthgrid .d.edge { box-shadow: inset 0 0 0 2px var(--ink); }
.monthgrid .d.blank { background: transparent; }

.backlink {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  padding: 4px 6px 4px 4px; font-size: 14px; font-weight: 600; color: var(--ink-2);
}
.backlink:hover { text-decoration: none; }
.backlink__dot {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 30px; height: 30px; padding: 10px; border-radius: 50%; background: var(--panel);
}
.backlink:hover .backlink__dot { background: var(--panel-2); }
.backlink__icon { flex-shrink: 0; }

/* ---------- the contact page ---------- */

.contact__email { font-size: 19px; font-weight: 700; }

/* The three accounts are reserved, not live, so each row says so rather than
   offering a link that goes nowhere. */
.social {
  max-width: 420px; border-top: 1px solid var(--line);
}
.social__row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.social__name { font-weight: 700; }
.social__status { font-size: 13px; color: var(--ink-3); }

/* ---------- site footer ---------- */

.sitefooter {
  margin-top: 36px; border-top: 1px solid var(--line);
  padding: 20px 0 32px;
}
.footernav { display: flex; justify-content: center; flex-wrap: wrap; gap: 4px 4px; }
.footerlink {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 10px; border-radius: 3px;
  font-size: 13px; font-weight: 600; color: var(--ink-2);
}
.footerlink:hover { background: var(--panel); color: var(--ink); text-decoration: none; }
.footerlink:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---------- desktop ---------- */

@media (min-width: 980px) {
  /* The home page. A taller photograph opens the page, with the next breaks
     as pills across the bottom of it. Below, the three calendars stand side
     by side. */
  .sitenav { display: flex; align-items: center; gap: 2px; flex-grow: 1; }
  .herotop { min-height: 460px; }
  .herotop__content { max-width: 1240px; margin: 0 auto; padding: 40px 20px 44px; }
  .herotop__title { font-size: clamp(32px, 3.4vw, 46px); max-width: 720px; }
  .herotop .peek { flex-direction: row; gap: 14px; }
  .herotop .peek__row { flex: 0 0 240px; }
  .chooser-head h1 { font-size: clamp(40px, 4vw, 54px); }

  /* The nav already marks the calendar being read, so the chip beside it
     would say the same thing twice. Only the way out of it stays. */
  .variation .chip { display: none; }

  .chooser { padding-top: 40px; padding-bottom: 12px; }
  .options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: stretch; }
  .option { padding: 22px 22px 22px 26px; }
  .chooser-actions { flex-direction: row; align-items: center; gap: 20px; }
  .btn--block { width: auto; min-width: 320px; }

  /* The calendar page. The photograph runs the full width behind the
     answer, with room for the title to breathe. */
  .hero { padding: 56px 0; }
  .hero__body { max-width: 720px; }
  .layout { display: grid; grid-template-columns: 380px 1fr; gap: 32px; align-items: start; margin-top: 28px; }
  /* Without this a grid item refuses to shrink below its content width and the
     year grid pushes the whole page sideways. */
  .layout > * { min-width: 0; }
  .layout .side { position: sticky; top: 72px; display: flex; flex-direction: column; gap: 16px; }
  .layout .section-head { margin-top: 0; }
  .yeargrid { min-width: 0; }
  .yeargrid .cell { width: 24px; height: 22px; }
  .yeargrid .head i { width: 24px; }
  .monthgrid { max-width: 420px; }
  .months { flex-direction: row; gap: 28px; }
}


/* =====================================================================
   The essential layout.

   One answer per screen. The countdown fills the phone, and everything
   that is useful but not the answer sits behind a disclosure. Density is
   the enemy here: a parent opens this with one question.
   ===================================================================== */

/* The hero holds the whole screen, so nothing competes with the answer
   and nothing has to be scrolled past to reach it. */
.hero--full {
  min-height: 78svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 24px 0 20px;
}
.hero--full .count b { font-size: clamp(78px, 26vw, 132px); }
.hero--full .count span { font-size: clamp(24px, 7vw, 32px); }
.hero--full h1 { font-size: clamp(30px, 9vw, 42px); }
.hero--full .dates { font-size: clamp(17px, 5vw, 21px); }
.hero--full .lines { font-size: 15px; }

/* A quiet cue that there is more, so the full-screen answer never reads
   as the end of the page. */
.scrollcue {
  margin-top: auto;
  padding-top: 24px;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.75;
}
.scrollcue::after {
  content: "";
  display: block;
  width: 10px; height: 10px;
  margin: 8px auto 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
}

/* Breaks are blocks. Terms are the lines between them. */
.breaks { display: flex; flex-direction: column; gap: 0; }

/* The same gradient as the hero, so a break block reads as a piece of the
   answer rather than a flat swatch. The chevron says it opens. */
.break {
  position: relative;
  display: block;
  padding: 22px 52px 24px 20px;
  border-radius: var(--radius);
  background: linear-gradient(150deg, #D95A21 0%, var(--holiday) 55%, var(--holiday-deep) 100%);
  color: var(--on-accent);
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.break::after {
  content: "";
  position: absolute; right: 24px; top: 50%;
  width: 10px; height: 10px; margin-top: -5px;
  border-right: 2.5px solid currentColor; border-top: 2.5px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.8;
}
.break:hover {
  text-decoration: none;
  transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(201,80,27,0.28);
}
.break--half { background: linear-gradient(150deg, #4A73D8 0%, var(--half) 55%, var(--half-deep) 100%); }
.break--half:hover { box-shadow: 0 10px 22px rgba(58,99,201,0.28); }
.break__kicker {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; opacity: 0.85; margin-bottom: 6px;
}
.break__name {
  font-family: var(--display); font-size: 28px; font-weight: 800;
  letter-spacing: -0.028em; line-height: 1.05;
}
.break__dates { font-size: 17px; font-weight: 600; margin-top: 6px; }
.break__len { font-size: 15px; opacity: 0.85; margin-top: 2px; }

/* A term block. Green, tinted rather than filled, so it reads as the span
   between two breaks and never competes with the break blocks around it. */
.term {
  margin: 12px 0;
  padding: 16px 18px;
  border-radius: var(--radius);
  background: var(--term-tint);
  border-left: 6px solid var(--term);
  color: var(--term-deep);
}
.term__kicker {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; opacity: 0.75;
}
.term__name {
  font-family: var(--display); font-size: 20px; font-weight: 800;
  letter-spacing: -0.02em; margin-top: 2px;
}
.term__dates { display: flex; flex-wrap: wrap; gap: 8px 28px; margin-top: 10px; }
.term__edge { display: flex; flex-direction: column; gap: 1px; }
.term__edge b {
  font-size: 10px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; opacity: 0.7;
}
.term__edge span { font-size: 16px; font-weight: 700; }
.term__meta { margin-top: 10px; font-size: 13px; color: var(--term-deep); opacity: 0.8; }

.adslot--inline { min-height: 64px; margin: 18px 0; }

/* Disclosures. Closed by default on a phone, opened on a wide screen. */
.disclose { margin-top: 18px; border-top: 1px solid var(--line); }
.disclose > summary {
  list-style: none;
  cursor: pointer;
  min-height: 56px;
  display: flex; align-items: center; justify-content: space-between;
  font-family: var(--display); font-size: 16px; font-weight: 800;
  letter-spacing: -0.01em;
}
.disclose > summary::-webkit-details-marker { display: none; }
.disclose > summary::after {
  content: "";
  width: 9px; height: 9px;
  border-right: 2px solid var(--ink-3);
  border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg);
  margin-left: 12px;
  flex-shrink: 0;
}
.disclose[open] > summary::after { transform: rotate(-135deg); }
.disclose > *:not(summary) { margin-bottom: 14px; }

@media (min-width: 980px) {
  /* On a wide screen there is room, so the hero stops eating the viewport
     and the disclosures are already open. */
  .hero--full { min-height: 0; padding: 56px 0; }
  .scrollcue { display: none; }
  .disclose { border-top: 0; margin-top: 22px; }
  .breaks { gap: 2px; }
}

.hero--full .lines { opacity: 0.95; }

/* A .wrap inside a flex column is a flex item, and its `margin: 0 auto`
   overrides the stretch, collapsing it to fit-content. Take the full width
   back explicitly. */
.hero > .wrap,
.hero--full > .scrollcue { width: 100%; }


/* =====================================================================
   The parts the site has and the mock did not.
   ===================================================================== */

/* ---------- the answer ---------- */

.hero p { margin: 0; }
.hero .length { font-size: clamp(19px, 5.2vw, 24px); font-weight: 800; }
.count { margin: 0; }
/* When there is no number to show, the words take the number's place rather
   than leaving a hole where the answer should be. */
.count--words {
  font-family: var(--display);
  font-size: clamp(28px, 8vw, 40px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.h1--detail { font-size: clamp(34px, 10vw, 52px); }
.h2--small { font-size: 22px; }

/* The teacher's line. Present, quieter than the learner dates above it. */
.lines__second { opacity: 0.82; font-size: 14px; }
/* Why a break is the shape it is, when the source needs explaining. */
.lines__note { opacity: 0.82; font-size: 13px; line-height: 1.45; max-width: 54ch; }
.term__second { margin-top: 4px; font-size: 13px; opacity: 0.75; }

/* ---------- the chooser, as a form ---------- */

.chooserform { display: flex; flex-direction: column; gap: 24px; }
.options { border: 0; margin: 0; padding: 0; min-width: 0; }

/* The radio is the control. It is placed under the card rather than removed,
   so the keyboard and the screen reader still have it. */
.option { position: relative; }
.option__input {
  position: absolute; top: 18px; right: 18px;
  width: 26px; height: 26px; margin: 0;
  opacity: 0; cursor: pointer;
}
.option:has(.option__input:checked) {
  border-color: var(--holiday);
  box-shadow: 0 3px 0 var(--holiday-deep), 0 8px 18px rgba(201,80,27,0.16);
}
.option:has(.option__input:checked)::before { background: var(--holiday); }
.option:has(.option__input:focus-visible) { outline: 3px solid var(--ink); outline-offset: 3px; }
.option__input:checked ~ .ring { border-color: var(--holiday); background: var(--holiday); }
.option__input:checked ~ .ring::after {
  content: "";
  position: absolute; left: 8px; top: 4px;
  width: 6px; height: 11px;
  border-right: 2.5px solid #fff; border-bottom: 2.5px solid #fff;
  transform: rotate(42deg);
}

/* ---------- where the dates come from ---------- */

.sourceyear { display: flex; flex-direction: column; gap: 4px; }
.sourceyear + .sourceyear { padding-top: 10px; border-top: 1px solid #DDD3C4; }
.sourceyear__year {
  font-size: 11px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-3);
}
.sourceyear__note { font-style: italic; }
/* A calendar that is out for comment is not a gazetted one. Say which it is. */
.flag {
  display: inline-block; font-size: 10px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 2px 6px; border-radius: 3px;
  background: var(--ink); color: var(--ground);
}
/* An unchecked date must never look checked. */
.verified--open { font-weight: 400; color: var(--ink-2); font-size: 12px; line-height: 1.45; }
.disclaimer { font-size: 13px; }
.rule-note { font-size: 12px; color: var(--ink-3); }

.gapcard { margin-top: 12px; }

/* The ISASA notice on an independent calendar page. Same padding and border
   as the coverage card, but the warning triangle marks it as the one a
   reader should not skip: the dates on this page may not be the reader's
   own school's dates. */
.noticecard {
  padding: 16px 18px; border-radius: var(--radius); margin: 16px 0 0;
  border: 1.5px dashed var(--ink-4); background: var(--panel-2);
  display: flex; flex-direction: column; gap: 6px;
}
.noticecard__head { display: flex; align-items: center; gap: 6px; }
.noticecard__icon { flex-shrink: 0; color: var(--holiday); }
.noticecard b { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-4); }
.noticecard p { margin: 0; font-size: 14px; color: var(--ink-2); }

/* ---------- odds and ends ---------- */

.main { min-width: 0; }
.section-head p.sub { margin: 0; }
.monthgrid .h abbr { text-decoration: none; border: 0; }
.breaks .adslot--2 { margin: 12px 0; }

/* A reader who arrives at an anchor should not land under the sticky header. */
:target { scroll-margin-top: 72px; }

/* The disclosures are closed in the markup. That is the phone layout, which
   is the one that matters: one idea per screen. A wide screen has the room,
   so a script opens them there. CSS cannot do it, because a closed <details>
   hides its content through the shadow slot rather than through display.

   With no script every panel is still one tap from the reader, on every
   device, and no content is lost. */

/* A half-term break can be followed straight away by an end-of-term holiday,
   with no term block between them to hold them apart. Two blocks that touch
   read as one, so they are separated here. */
.break + .break { margin-top: 8px; }

/* The header has three things in it and a 320px phone does not have room for
   all three at full width. The domain gives way first, then the wordmark, and
   the variation being read keeps its space: on a return visit that is the part
   the reader checks. */
.siteheader .wrap { min-width: 0; }
.wordmark { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.variation { flex-shrink: 0; }
@media (max-width: 400px) {
  .wordmark__tld { display: none; }
  .siteheader .wrap { gap: 10px; }
}

/* The radio has to sit above the tick that is drawn under it, or a click on
   the control lands on the decoration instead. */
.option__input { z-index: 1; }
