/* Tempo. A chalk page, a true ink, and one electric yellow.
   The memorable thing is the timetable: the week set as one enormous
   condensed block on a yellow field, five days, ten class times, heavy ink
   rules running the full content width. It is the biggest type on the page,
   it is real information, and it is the only thing on the page set in
   capitals. Everything else is quiet: sentence case, one condensed display
   against one plain text face, no cards, no shadows, no eyebrow rules. */

/* Big Shoulders Display, Patric King / XOtype, SIL Open Font License 1.1.
   bigshoulders-OFL.txt ships beside it. Subset to Latin basic plus curly
   quotes, dashes, the ellipsis and (c), with the weight axis kept from 500 to
   800 so the page gets two display weights out of one 14 KB file. It lives in
   this folder: the page asks the internet for nothing. */
@font-face {
  font-family: "Big Shoulders Display";
  src: url(bigshoulders-subset.woff2) format("woff2");
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Colour. Only --accent and --tint are meant to be changed. See README.md. */
  --bg: #eff0ea;         /* chalk, deliberately not cream */
  --ink: #12130f;        /* near-black: every rule, every button */
  --muted: #4d514a;      /* secondary text on --bg and --tint */
  --accent: #ffdd00;     /* timetable field and closing band, nowhere else */
  --accent-ink: #12130f; /* text on --accent */
  --tint: #f6f1d9;       /* a pale wash of the accent: alternate bands */
  --rule: #12130f;       /* the timetable rules and the list rules */
  --pale: #b6bab0;       /* secondary text inside the ink bands */

  /* Type. A condensed display against the plainest text face on both
     platforms; they agree about nothing, which is the point. */
  --display: "Big Shoulders Display", "Arial Narrow", "Liberation Sans Narrow",
             "Roboto Condensed", Impact, sans-serif;
  --sans: Verdana, Tahoma, "DejaVu Sans", Geneva, sans-serif;

  /* Type scale, chosen at three widths rather than left to the clamps. The
     day names sit at the top of it and the headline sits well below them: on
     this page the data is the display type, at 1440 and on a phone. Every
     floor below is the size the page renders at 390 and at 320, picked as a
     whole pixel; every ceiling is the size at 1440. README, Type. */
  --t-day: clamp(3.25rem, 13vw, 8rem);
  --t-display: clamp(1.875rem, 5.5vw, 3rem);
  --t-num: clamp(2.25rem, 6vw, 3.5rem);
  --t-statement: clamp(1.4375rem, 3.4vw, 2.25rem);
  --t-time: clamp(1rem, 2.6vw, 1.625rem);
  --t-sec: clamp(1.3125rem, 2.4vw, 1.875rem);
  --t-h: clamp(1.125rem, 2vw, 1.4375rem);
  --t-btn: clamp(1rem, 1.6vw, 1.125rem);
  --t-lead: clamp(1.0625rem, 1.5vw, 1.1875rem);
  --t-body: 1rem;
  --t-small: 0.875rem;

  /* Space. */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 1rem;
  --s4: 1.5rem;
  --s5: 2.5rem;
  --s6: 4rem;
  --pad: clamp(1.125rem, 5vw, 4rem);
  --band: clamp(2.5rem, 6vw, 5rem);

  --rule-weight: 5px;
  --measure: 50ch;
  --wrap: 74rem;
}

/* ---------- base ---------- */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.5;
  overflow-wrap: break-word;
}

h1, h2, h3 { margin: 0; }

img { max-width: 100%; height: auto; }

p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

/* The display face carries the timetable, the headlines and the buttons. The
   weight axis does the work a second family would otherwise do: 800 for the
   days and the promises, 600 for the times and the smaller headings. */
.hero__promise,
.week__day,
.week__time,
.statement,
.section-head,
.row__name,
.hours__day,
.cta__head,
.btn,
.wordmark,
.plate__name,
.facts__name,
.facts__n,
.step::before {
  font-family: var(--display);
  letter-spacing: -0.01em;
}

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding-inline: var(--pad);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--ink);
  color: var(--bg);
  padding: var(--s2) var(--s3);
  text-decoration: none;
}
.skip:focus { left: 0; }

/* ---------- top bar ---------- */

.topbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2) var(--s3);
  padding: var(--s3) var(--pad);
  border-bottom: 2px solid var(--rule);
}

.wordmark {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.1;
  min-width: 0;
}

.topbar__link {
  display: inline-block;
  font-size: var(--t-small);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
  white-space: nowrap;
  padding: 0.3rem 0.25rem;
}

/* ---------- hero ---------- */

.hero__top { padding-block: var(--s5); }

.hero__promise {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.02em;
  max-width: 22ch;
  margin-bottom: var(--s4);
  text-wrap: balance;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.45;
  max-width: var(--measure);
}

.hero__act { margin-top: var(--s4); margin-bottom: 0; }

.act__second {
  margin-top: var(--s2);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--muted);
  max-width: 44ch;
}
.act__second a {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
  display: inline-block;
  padding: 0.2rem 0.1rem;
}
.cta .act__second { color: var(--accent-ink); }

.aside {
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--muted);
  max-width: var(--measure);
}

/* ---------- the week ---------- */
/* The one thing on this page anyone would describe afterwards, and the only
   capitals on it. The day names are the top of the type scale; the times sit
   on the same baseline because the table cells align on baseline, which is
   what makes the block read as one object rather than a heading with labels
   beside it. */

.week-field {
  background: var(--accent);
  color: var(--accent-ink);
  padding: var(--s4) var(--pad) var(--s5);
  /* Nothing animates here. A wipe or a fade on this block was tried and cut:
     every tool that pauses animations to take a screenshot, the kit's own
     review included, captures it at the start and reports a hero with nothing
     in it. The biggest thing on the page renders whole, always. */
}

.week {
  width: 100%;
  /* .week-field carries --pad OUTSIDE its content box; .wrap carries it INSIDE
     --wrap. Subtracting it here is what puts the first rule on the same left
     edge as every heading below it at widths above 1184px. */
  max-width: calc(var(--wrap) - var(--pad) * 2);
  margin: 0 auto;
  border-collapse: collapse;
}

.week__cap {
  text-align: left;
  padding-bottom: var(--s2);
  font-size: var(--t-small);
  line-height: 1.4;
}

.week th,
.week td {
  border-top: var(--rule-weight) solid var(--rule);
  padding-block: var(--s2) var(--s3);
  vertical-align: baseline;
}

.week tr:last-child th,
.week tr:last-child td {
  border-bottom: var(--rule-weight) solid var(--rule);
}

.week__day {
  width: 99%;
  text-align: left;
  font-size: var(--t-day);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}

.week__time {
  text-align: right;
  white-space: nowrap;
  font-size: var(--t-time);
  font-weight: 600;
  line-height: 1;
  padding-left: var(--s3);
}

/* ---------- buttons ---------- */
/* The 3px ink border is the edge of the button in every state, so its boundary
   against the page never drops below the ink-on-page ratio. Keep the border. */

.btn {
  display: inline-block;
  background: var(--ink);
  color: var(--bg);
  border: 3px solid var(--ink);
  padding: 0.5em 1em;
  font-size: var(--t-btn);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  transition: background-color 110ms linear, color 110ms linear;
}
.btn:hover {
  background: var(--accent);
  color: var(--accent-ink);
}
.cta .btn:hover,
.btn:active {
  background: var(--bg);
  color: var(--ink);
}

/* ---------- bands ---------- */

.band { padding-block: var(--band); }
.band--tint { background: var(--tint); }
.band--ink {
  background: var(--ink);
  color: var(--bg);
}
.band--ink :focus-visible,
.footer :focus-visible { outline-color: var(--accent); }

.section-head {
  font-size: var(--t-sec);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: var(--s4);
}

.statement {
  font-size: var(--t-statement);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.02em;
  max-width: 20ch;
  margin-bottom: var(--s4);
}

/* ---------- text and picture pairs ---------- */
/* The frame is the constant. With no photograph the frame holds something
   true -- what is in the room, or who the coach is -- set in the page's own
   ruled grammar. With a photograph the frame holds the photograph and the
   stand-in goes. Neither state leaves a column stranded, because in both
   states the column is occupied. */

.pair { display: grid; gap: var(--s5); }
.pair__text p { max-width: var(--measure); }
.pair__text--lede p {
  font-size: var(--t-lead);
  line-height: 1.45;
}

.shot {
  margin: 0;
  border-block: var(--rule-weight) solid var(--rule);
}

/* A photograph is cropped, never stretched, and it is re-cropped on a phone:
   at 354px of width a 4:5 portrait is 442px tall and a 3:2 room shot 236px,
   which is most of a screen each. Below 46em the browser cuts the same file
   into a band and a square instead. The ratios in the markup are the desktop
   ones, which is what the owner should supply. */
.shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 12 / 5;
  object-fit: cover;
}
.shot--portrait img { aspect-ratio: 1 / 1; }

@media (min-width: 46em) {
  .shot img { aspect-ratio: 3 / 2; }
  .shot--portrait img { aspect-ratio: 4 / 5; }
}

.shot:not(.is-empty) {
  padding-block-start: var(--s2);
}
.shot:not(.is-empty) .shot__cap {
  margin-top: var(--s2);
}

.shot__cap {
  border-top: 2px solid var(--rule);
  padding-top: var(--s2);
  padding-bottom: var(--s2);
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--muted);
}

/* The stand-ins, shown only while the slot is empty. Below 46em the figure
   itself goes: there is no second column on a phone, so an empty frame
   strands nothing by leaving, and it costs 460px of a 4,500px budget by
   staying. The frame and its stand-in come back the moment there is a column
   beside the text, and a real photograph shows at every width. */
.shot.is-empty { display: none; }
.shot:not(.is-empty) .facts,
.shot:not(.is-empty) .plate { display: none; }

.facts {
  width: 100%;
  border-collapse: collapse;
  margin-block: var(--s3) var(--s4);
}
.facts__cap {
  text-align: left;
  padding-bottom: var(--s2);
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--muted);
}
.facts th,
.facts td {
  border-top: 2px solid var(--rule);
  padding-block: var(--s2);
  vertical-align: baseline;
}
.facts__name {
  width: 99%;
  text-align: left;
  font-size: var(--t-h);
  font-weight: 600;
  line-height: 1.2;
}
.facts__n {
  text-align: right;
  font-size: var(--t-h);
  font-weight: 800;
  line-height: 1.2;
  padding-left: var(--s3);
  white-space: nowrap;
}

.plate {
  display: grid;
  gap: var(--s2);
  margin: 0;
  padding-block: var(--s4) var(--s5);
}
.plate__name {
  font-size: var(--t-statement);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.02em;
}
.plate__role {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--muted);
}

/* ---------- ruled lists: services, and what two people said ---------- */
/* The heavy rules are the list, at the same weight as the timetable rules, so
   the page carries one line thickness and not four. */

.rows { display: grid; }

.row {
  border-top: var(--rule-weight) solid var(--rule);
  padding-block: var(--s3) var(--s4);
  display: grid;
  gap: var(--s2);
}
/* The closing rule under the last row shuts the list off the way the timetable
   is shut off. It sits tighter than the gaps between rows so it reads as the
   end of the set and not as an empty extra row. */
.rows .row:last-child {
  border-bottom: var(--rule-weight) solid var(--rule);
  padding-bottom: var(--s3);
}

/* 600, not the heading's 800: a service name is a row label, and at the same
   weight and size as the section heading above it the two read as one list. */
.row__name {
  font-size: var(--t-h);
  font-weight: 600;
  line-height: 1.15;
}

.row__note {
  max-width: var(--measure);
  color: var(--muted);
  line-height: 1.5;
}

.rows--said { margin-top: var(--s5); }

.row__said {
  margin: 0;
  font-size: var(--t-lead);
  line-height: 1.4;
  max-width: var(--measure);
}

.row__who {
  font-size: var(--t-small);
  color: var(--muted);
  margin: 0;
}

/* ---------- your first forty-five minutes ---------- */
/* Numbers belong here and nowhere else on the page: this is the only real
   sequence. The band is the timetable inverted, a heavy chalk rule over each
   step with the numeral in chalk under it. The accent stays out of this band
   on purpose: acid yellow on near-black is the one pairing this design exists
   to avoid, and the yellow belongs to the timetable and the closing band. */

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: step;
  display: grid;
  gap: var(--s3);
}

.step {
  counter-increment: step;
  border-top: var(--rule-weight) solid var(--bg);
  padding-top: var(--s3);
  font-size: var(--t-lead);
  line-height: 1.4;
  max-width: var(--measure);
}

.step::before {
  content: counter(step);
  display: block;
  font-size: var(--t-num);
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.04em;
  color: var(--bg);
  margin-bottom: var(--s2);
}

/* ---------- closing call ---------- */

.cta {
  background: var(--accent);
  color: var(--accent-ink);
  padding-block: var(--band);
}

.cta__head {
  font-size: var(--t-statement);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.02em;
  max-width: 20ch;
  margin-bottom: var(--s4);
}

.cta .lead { margin-bottom: var(--s5); }
.cta p:last-child { margin-bottom: 0; }

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

.footer {
  background: var(--ink);
  color: var(--bg);
  padding-block: var(--band) var(--s4);
}

/* Contact runs as one band across the top of the footer and the room hours
   come back as the timetable at a quarter of the hero's voice: the same ruled
   rows, the same day-left, time-right shape, 3px rules in --pale instead of
   5px in ink. The close of the page answers the top of it. Deliberately not a
   contact list on the left with an opening-hours list on the right. */

.contact {
  list-style: none;
  margin: 0 0 var(--s4);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s5);
  line-height: 1.4;
  font-size: var(--t-body);
}

.contact a {
  display: inline-block;
  overflow-wrap: anywhere;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.25em;
  padding: 0.25rem 0.15rem;
}

.topbar__link,
.contact a { transition: background-color 110ms linear, color 110ms linear; }

.topbar__link:hover,
.contact a:hover {
  background: var(--accent);
  color: var(--accent-ink);
}

.hours {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--s4);
}

.hours__cap {
  text-align: left;
  padding-bottom: var(--s2);
  font-size: var(--t-small);
  line-height: 1.4;
  color: var(--pale);
}

.hours th,
.hours td {
  border-top: 3px solid var(--pale);
  padding-block: var(--s2);
  vertical-align: baseline;
}

.hours tr:last-child th,
.hours tr:last-child td {
  border-bottom: 3px solid var(--pale);
}

.hours__day {
  width: 99%;
  text-align: left;
  font-size: var(--t-h);
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
}

.hours__time {
  text-align: right;
  white-space: nowrap;
  font-size: var(--t-small);
  line-height: 1.4;
  padding-left: var(--s3);
}

.footer__note {
  max-width: var(--measure);
  color: var(--pale);
  font-size: var(--t-small);
  line-height: 1.6;
}

.footer__copy {
  margin-top: var(--s5);
  font-size: var(--t-small);
  color: var(--pale);
}

/* ---------- wider screens ---------- */

@media (min-width: 46em) {
  .shot.is-empty { display: block; }

  /* Two columns that both carry something: the promise on the left, and the
     sentence and the button together on the right, so the button belongs to
     the words that ask for it rather than floating off the edge. */
  .hero__top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: var(--s4) var(--s6);
    align-items: start;
    padding-block: var(--s6) var(--s5);
  }
  .hero__promise {
    grid-column: 1;
    grid-row: 1 / span 2;
    max-width: 16ch;
    margin-bottom: 0;
  }
  .hero__act { margin-top: var(--s4); }
  /* The second choice belongs under the button it is second to, not back at
     the left edge where auto-placement puts it. */
  .hero__top .act__second { grid-column: 2; }

  .week-field { padding-block: var(--s5) var(--s6); }

  .pair {
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: var(--s6);
    align-items: start;
  }

  .row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: var(--s4) var(--s5);
    align-items: start;
    padding-block: var(--s3) var(--s5);
  }
  .rows .row:last-child { padding-bottom: var(--s4); }

  /* Side by side, and both shut off at the bottom: in a two-column grid
     :last-child would rule one of them and not the other. */
  /* The quotes stack inside the text column rather than spanning the section,
     which is what keeps the column as tall as a filled 4:5 portrait beside it.
     Ruled top and bottom, because :last-child would rule one and not the
     other once they are in a column. */
  .rows--said { margin-top: var(--s5); }
  .rows--said .row {
    grid-template-columns: minmax(0, 1fr);
    border-bottom: var(--rule-weight) solid var(--rule);
    padding-block: var(--s3) var(--s4);
  }
  .rows--said .row + .row { margin-top: var(--s5); }
  .rows--said .row__said { max-width: none; }
}

@media (min-width: 64em) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5) var(--s6); }
  .hero__top { padding-block: var(--s6); }

  /* The closing band answers the hero: the promise left, the sentence and the
     button in the column beside it, so the field is used rather than half
     painted. */
  .cta .wrap {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    gap: 0 var(--s6);
    align-items: start;
  }
  .cta__head { grid-row: 1 / span 2; margin-bottom: 0; max-width: 24ch; }
  .cta .act__second { grid-column: 2; }
  .cta .lead { margin-bottom: var(--s4); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
