/* Testimonial Recorder: hub (choose-page) styles.
   GB light surface: condensed display, hairline-ruled menu rows, red spent
   only on the chevrons and the press state.
   Theme values (including fonts, via the FontFace API in hub.js) are
   overridden per school by hub.js from window.HUB.theme. */

:root {
  --bg: #fcfcfc;
  --ink: #1a1a1a;
  --muted: #575756;
  --faint: rgba(26, 26, 26, 0.6);
  --line: rgba(26, 26, 26, 0.14);
  --accent: #e2211c;
  --accent-down: #b5150f;
  /* What sits ON the accent, and what the accent becomes when it has to carry
     small text. Both default to the GB answer, which is the one case where the
     true accent works untouched: white on GB red is 4.58:1 and the red itself
     is 4.58:1 on this ground. A brand pack overrides them when its accent is
     not that forgiving; see src/brands/premier-martial-arts.js. */
  --on-accent: #fcfcfc;
  --accent-text: var(--accent);
  --radius: 10px;
  --display: "Adihaus DIN Cond", "Arial Narrow", "Segoe UI", system-ui, sans-serif;
  --sans: "Adihaus DIN", "Segoe UI", system-ui, sans-serif;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

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

body {
  font-family: var(--sans);
  background: var(--bg);
  color: var(--ink);
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  padding: calc(2.25rem + env(safe-area-inset-top)) 1.375rem calc(2rem + env(safe-area-inset-bottom));
  -webkit-font-smoothing: antialiased;
}

.hub {
  width: 100%;
  max-width: 26.5rem;
  margin: auto;
}

/* crest */
.hub-head { text-align: center; }
.hub-logo { height: 3.5rem; width: auto; display: inline-block; }
.hub-school {
  margin-top: 0.875rem;
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.8125rem;
  color: var(--muted);
}

.hub-title {
  margin-top: 1.375rem;
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
  line-height: 0.98;
  font-size: clamp(2.625rem, 13vw, 3.5rem);
  text-align: center;
  color: var(--ink);
  text-wrap: balance;
}
.hub-intro {
  margin: 0.875rem auto 0;
  text-align: center;
  color: var(--muted);
  /* 18px, matching the recorder landing screens. Deliberately NOT applied to
     .mode-card-desc: those are tuned to sit on exactly one line each so every
     row is the same height, and enlarging them rewraps the longest one
     ("Someone else holds the phone. 4 questions.") and breaks that rhythm. */
  font-size: 1.125rem;
  line-height: 1.5;
  max-width: 30ch;
  text-wrap: pretty;
}

/* mode menu: a ruled list, not cards. The labels carry the distinction
   themselves ("selfie" = you hold the phone, "interview" = someone else films
   and asks), so the list needs no section headings to explain itself. */
.hub-modes {
  margin-top: 2.25rem;
  display: block;
  border-top: 1px solid var(--line);
}
/* --- the site index ---

   Not the same shape as a school hub, and deliberately so. A hub lists a
   handful of modes and gives each a full ruled row with a description, which
   is right when the reader has already chosen a school and is choosing what to
   film. The index answers a different question: which of seven schools, then
   which of its hubs. Seven schools times three or four hubs is twenty-two of
   those rows, and the school name would be a heading repeated above every run.

   So the school is the row and its hubs are links on it. Same hairline-ruled
   list, same condensed uppercase, one level flatter. */
.hub-index { margin-top: 2.25rem; }
.hub-brand + .hub-brand { margin-top: 2.625rem; }

/* The brand says itself in its own colour rather than next to a coloured
   square. --accent-text is the hue-matched shade that clears 4.5:1 on this
   ground, which the true accent does for GB red and does not for the other
   two; a decorative swatch would have had the same problem at 2.45:1 and
   carried no information the name does not. */
.hub-brand-name {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  font-size: 0.875rem;
  line-height: 1.2;
  color: var(--accent-text);
}
.hub-brand-schools {
  margin-top: 0.75rem;
  border-top: 1px solid var(--line);
}

.hub-school-row {
  padding: 0.5rem 0.25rem 1.25rem;
  border-bottom: 1px solid var(--line);
}
/* Same size and face as a hub's own row titles, so moving from this page into
   a school does not feel like moving between two products. */
/* The All chip sits NEXT TO the name, not at the far edge of the row. It was
   space-between, which looks fine while the name nearly fills the line and
   strands the chip in an empty corner the moment it does not: at the container's
   full width there was an inch of nothing between BAKERSFIELD and its own link,
   and the chip read as a stray element rather than as part of that school.
   The chip sets the row's height at 44px, so the name needs no padding. */
.hub-school-head { display: flex; align-items: center; gap: 0.875rem; }
.hub-school-name {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  font-size: 1.4375rem;
  line-height: 1.05;
  color: var(--ink);
}
/* A GRID, not a wrapping flex row, and the reason is the fifth chip. Five
   chips wrapping freely split four-and-one at every width that matters,
   stranding Ads alone under a full line; three even columns split them three
   and two, and every chip in every school lines up with the one above it.
   auto-fit holds three columns from 360px to the container's own 424px cap,
   so the shape does not change between a phone and a desktop. */
.hub-links {
  list-style: none;
  margin-top: 0.8125rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6.25rem, 1fr));
  gap: 0.4375rem;
}
.hub-links > li { display: flex; }
.hub-link {
  display: flex;
  flex: 1;
  justify-content: center;
  align-items: center;
  gap: 0.4375rem;
  min-height: 2.75rem;
  padding: 0 0.8125rem;
  border: 1px solid var(--line);
  border-radius: 7px;
  font-size: 0.9375rem;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  touch-action: manipulation;
}
/* Quieter, and also SAID: hub.js appends the word Staff and puts "staff only"
   in the accessible name. A grey that only sighted readers can compare is not
   a way to tell somebody a page is not for them. */
.hub-link--staff .hub-link-label { color: var(--muted); }
.hub-link-tag {
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.625rem;
  color: var(--faint);
}
/* Atomic, and for the same reason the rows above are: a background that fades
   while its text colour snaps leaves the two disagreeing mid-transition. */
.hub-link:active {
  background: var(--accent);
  border-color: var(--accent);
}
.hub-link:active .hub-link-label,
.hub-link:active .hub-link-tag { color: var(--on-accent); }
@media (hover: hover) {
  .hub-link:hover { border-color: rgba(26, 26, 26, 0.32); }
}
.hub-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* The chip that goes to the school's own index rather than into a hub. Its
   chevron is the whole distinction and it is the same one the school name
   carries, so "leads to a page of links" is marked one way on this site
   instead of two. No fill and no heavier border: it is a sibling of the four,
   not a call to action above them. */
.hub-link-go {
  flex: 0 0 auto;
  width: 0.4375rem;
  height: 0.4375rem;
  border-top: 2px solid var(--accent);
  border-right: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 140ms var(--ease-out);
}
.hub-link--all:active .hub-link-go { border-color: var(--on-accent); }
@media (hover: hover) {
  .hub-link--all:hover .hub-link-go { transform: rotate(45deg) translate(2px, -2px); }
}

.mode-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-height: 4.75rem;
  padding: 1.125rem 0.25rem;
  border-bottom: 1px solid var(--line);
  text-decoration: none;
  color: inherit;
  touch-action: manipulation;
}
/* No transition on the background, deliberately. It used to fade over 140ms while
   the title and description colours snapped instantly, so for the length of the
   fade the two disagreed: on release the row was still red while the text had
   already jumped back to near-black, which is the "red row with black writing"
   people were seeing on their phones. A press state has to change atomically or
   not at all. The 4% hover tint appearing instantly is imperceptible; the chevron
   keeps its transform transition, which cannot affect contrast. */
/* press = the row floods GB red (same mechanic as the recorder's prompt picker).
   Hover/press must never change the text column's width: an earlier version
   inset the padding on hover, which narrowed the description enough to rewrap
   it onto an extra line and jolt every row below. The affordance rides on the
   chevron's transform instead, which cannot reflow anything. */
.mode-card:active { background: var(--accent); }
/* var(--on-accent), not #fff. This was hardcoded white while only Gracie Barra
   existed, where white on red is 4.58:1. On PMA green it is 3.14:1 and on RGA
   orange 2.45:1, so a pressed row on either of those schools' hubs was
   unreadable for as long as a thumb held it down. */
.mode-card:active .mode-card-title { color: var(--on-accent); }
.mode-card:active .mode-card-desc { color: var(--on-accent); opacity: 0.9; }
.mode-card:active .mode-card-go { border-color: var(--on-accent); transform: rotate(45deg) translate(2px, -2px); }
@media (hover: hover) {
  .mode-card:hover { background: rgba(26, 26, 26, 0.04); }
  .mode-card:hover .mode-card-go { transform: rotate(45deg) translate(2px, -2px); }
}
.mode-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: 4px;
}

.mode-card-body { flex: 1; min-width: 0; }
.mode-card-title {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.015em;
  font-size: 1.4375rem;
  line-height: 1.05;
  color: var(--ink);
}
.mode-card-desc {
  display: block;
  margin-top: 0.3125rem;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--muted);
}

/* chevron */
.mode-card-go {
  flex: 0 0 auto;
  width: 0.6875rem;
  height: 0.6875rem;
  border-top: 2px solid var(--accent);
  border-right: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: border-color 140ms var(--ease-out), transform 140ms var(--ease-out);
}

.hub-foot {
  margin-top: 1.75rem;
  text-align: center;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--faint);
}

/* one orchestrated page-load: crest settles, then the rows and footer follow
   in document order. hub.js stamps --stagger on each in sequence, so the
   cascade survives however many modes a school lists. */
@media (prefers-reduced-motion: no-preference) {
  .hub-head, .hub-title, .hub-intro {
    animation: hub-rise 560ms var(--ease-out) both;
  }
  .hub-title { animation-delay: 60ms; }
  .hub-intro { animation-delay: 110ms; }
  .mode-card, .hub-school-row, .hub-brand-name, .hub-foot {
    animation: hub-rise 480ms var(--ease-out) both;
    animation-delay: calc(170ms + var(--stagger, 0) * 50ms);
  }
  @keyframes hub-rise {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
  }
}
