/* ==========================================================================
   Jerry Campbell Football — hand-written component layer.

   The site's main stylesheet (app.css) is a compiled Tailwind build. There is
   no longer a Node toolchain in this project, so anything added after that
   build is written here as plain CSS using the same tokens. Loaded site-wide
   from includes/header.php, right after app.css.

   Tokens (sampled from logo.png, same values app.css uses):
     maroon #480F28 · deep red #901A1D · crimson #D42725 · silver #D6D6D6
   ========================================================================== */

:root {
  --jc-maroon: #480F28;
  --jc-maroon-700: #6B1A33;
  --jc-maroon-50: #FBF4F6;
  --jc-red-deep: #901A1D;
  --jc-crimson: #D42725;
  --jc-crimson-50: #FDF2F2;
  --jc-chalk: #F7F7F8;
  --jc-steel-100: #F1F2F3;
  --jc-steel-200: #E3E5E7;
  --jc-steel-300: #CBCED2;
  --jc-steel-400: #9CA1A8;
  --jc-steel-500: #6F767E;
  --jc-steel-600: #555C64;
  --jc-steel-800: #2A2F34;
  --jc-ok: #047857;
  --jc-ok-bg: #ECFDF5;
  --jc-warn: #B45309;
  --jc-warn-bg: #FFFBEB;
  --jc-info: #1D4ED8;
  --jc-info-bg: #EFF6FF;
  --jc-radius: 14px;
  --jc-shadow: 0 1px 2px rgba(24, 6, 14, .06), 0 8px 24px -12px rgba(24, 6, 14, .18);
  --jc-shadow-lg: 0 2px 4px rgba(24, 6, 14, .07), 0 22px 48px -20px rgba(24, 6, 14, .32);
  /* "… Fallback" sits directly behind each webfont: it is local Arial carrying
     that face's metrics, so text does not resize when the woff2 swaps in.
     Declared in assets/css/fonts.css. */
  --jc-display: "Barlow Condensed", "Barlow Condensed Fallback", "Arial Narrow", Arial, sans-serif;
  --jc-sans: Inter, "Inter Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* --------------------------------------------------------------------------
   Shared primitives
   -------------------------------------------------------------------------- */

.jc-panel {
  background: #fff;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  box-shadow: var(--jc-shadow);
}

.jc-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  padding: 1rem 1.15rem;
  border-bottom: 1px solid var(--jc-steel-200);
}

.jc-panel-head h2,
.jc-panel-head h3 {
  margin: 0;
  font-family: var(--jc-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--jc-maroon);
}

.jc-panel-body { padding: 1.15rem; }

.jc-muted  { color: var(--jc-steel-500); }
.jc-small  { font-size: .8125rem; }
.jc-strong { font-weight: 600; color: var(--jc-steel-800); }
.jc-right  { text-align: right; }
.jc-nowrap { white-space: nowrap; }
.jc-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .8125rem;
}

.jc-stack > * + * { margin-top: .85rem; }
.jc-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
}

/* Status pills — one vocabulary for orders, payments, bookings, threads. */
.jc-pill {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .2rem .6rem;
  border-radius: 999px;
  font-family: var(--jc-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.jc-pill-ok      { background: var(--jc-ok-bg);     color: var(--jc-ok); }
.jc-pill-warn    { background: var(--jc-warn-bg);   color: var(--jc-warn); }
.jc-pill-info    { background: var(--jc-info-bg);   color: var(--jc-info); }
.jc-pill-danger  { background: var(--jc-crimson-50); color: #B01B1A; }
.jc-pill-neutral { background: var(--jc-steel-100); color: var(--jc-steel-600); }

/* Flash messages */
.jc-flash {
  display: flex;
  align-items: flex-start;
  gap: .7rem;
  padding: .85rem 1rem;
  border-radius: 12px;
  border: 1px solid transparent;
  font-size: .95rem;
  line-height: 1.5;
}
/* An explicit size here too: the flash is used on the dashboard, which does
   not load the compiled Tailwind file, so the icon's h-5/w-5 would not resolve. */
.jc-flash svg { flex: 0 0 auto; width: 1.25rem; height: 1.25rem; margin-top: .1rem; }
.jc-flash-ok    { background: var(--jc-ok-bg);      border-color: #A7F3D0; color: #065F46; }
.jc-flash-error { background: var(--jc-crimson-50); border-color: #F7C8C7; color: #8A1513; }
.jc-flash-info  { background: var(--jc-info-bg);    border-color: #BFDBFE; color: #1E3A8A; }
.jc-flash-warn  { background: var(--jc-warn-bg);    border-color: #FDE68A; color: #92400E; }

/* --------------------------------------------------------------------------
   Header utility strip

   Address + phone + email + three tools + Follow is more than the 1256px of
   container content at 1320px, so flex was shrinking the items and every
   label broke onto a second line ("Playbook / Finder"). Nothing in the strip
   may wrap: the one item allowed to give way is the address, which shortens
   to an ellipsis and then drops out entirely below 1200px, where the footer
   and the mobile drawer still carry it.
   -------------------------------------------------------------------------- */

.util-strip,
.util-strip a,
.util-strip span { white-space: nowrap; }

.util-strip-tools,
.util-strip-social { flex: 0 0 auto; }

/* Only the address may shrink; its siblings keep their natural width. Both
   selectors have to carry the same weight, or `> a` wins for the address too
   and the whole group overflows into the next one. */
.util-strip-contact { min-width: 0; }
.util-strip-contact > a { flex: 0 0 auto; }
.util-strip-contact > .util-strip-address { flex: 0 1 auto; min-width: 0; }
.util-strip-address > span:first-child { flex: 0 0 auto; }
.util-strip-address > span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The display name comes from the account, so cap it instead of letting a
   long one push the strip over the edge. */
.util-strip-name {
  display: inline-block;
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

@media (max-width: 1199.98px) {
  .util-strip-address { display: none; }
}

/* --------------------------------------------------------------------------
   Main bar breakpoints

   The compiled Tailwind build only carries the variants it was built with
   (xl:flex, xl:hidden, 2xl:inline-flex), so the breakpoints the markup needs
   now are set here instead — same cascade position, no toolchain required.

   Measured at 1024px: logo 180 + the eight short labels 512 + the icon rail
   148 + gaps 32 = ~872 inside a 960px container. The nav fits from lg up, so
   a 1024- or 1366-wide laptop no longer gets a hamburger over an empty bar.
   -------------------------------------------------------------------------- */

@media (min-width: 1024px) {
  .site-nav   { display: flex; gap: 1rem; }
  .nav-burger { display: none; }
  /* The drawer is unreachable here, and JS adds .flex when it opens — so the
     body scroll lock cannot strand a hidden drawer on a resize. */
  #mobileNav,
  #mobileNavOverlay { display: none !important; }
}

@media (min-width: 1280px) {
  .site-nav { gap: 1.25rem; }
  /* Shop Now from xl rather than 2xl: 203px of slack at 1280, and without it
     the right of the bar reads as empty at 1280–1535. */
  .nav-cta  { display: inline-flex; }
}

@media (min-width: 1536px) {
  .site-nav { gap: 1.5rem; }
}

/* --------------------------------------------------------------------------
   Signed-in profile menu (site header + mobile drawer)

   Signed out, the header keeps the plain user icon that links to the login
   page. Signed in, it becomes an avatar + name button that opens the places
   people actually come back for, so the dashboard is one click from any page
   instead of a guess at what the icon does.
   -------------------------------------------------------------------------- */

.user-menu { position: relative; }

.user-menu-trigger {
  display: flex;
  align-items: center;
  gap: .5rem;
  height: 2.75rem;
  max-width: 13.5rem;
  padding: 0 .5rem;
  border-radius: 10px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--jc-maroon);
  transition: background-color .2s ease, color .2s ease;
}
.user-menu-trigger:hover { background: var(--jc-maroon-50); }
.user-menu-trigger:focus-visible { outline: 2px solid var(--jc-crimson); outline-offset: 2px; }

.user-avatar {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--jc-maroon-700), var(--jc-crimson));
  color: #fff;
  font-family: var(--jc-display);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .04em;
  line-height: 1;
}
.user-avatar-lg { width: 2.6rem; height: 2.6rem; font-size: .95rem; }

.user-menu-name {
  overflow: hidden;
  font-family: var(--jc-display);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.user-menu-caret { flex: 0 0 auto; color: var(--jc-steel-400); transition: transform .25s ease; }
.user-menu-trigger[aria-expanded="true"] .user-menu-caret { transform: rotate(180deg); }

/* The bar is measured, not guessed: with the name shown there is exactly 0px
   of slack left at 1280. So the name goes at 1320, where the container stops
   growing, and below 1200 the caret goes too — leaving the avatar the same
   footprint as the icon button it replaced (41px of slack at 1024). The
   utility strip still spells the name out from 1200 up. */
@media (max-width: 1319.98px) {
  .user-menu-name { display: none; }
  .user-menu-trigger { max-width: none; }
}

@media (max-width: 1199.98px) {
  .user-menu-caret { display: none; }
  .user-menu-trigger { gap: 0; padding: 0 .5rem; }
}

.user-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + .5rem);
  z-index: 60;
  width: min(19rem, calc(100vw - 2rem));
  padding: .4rem;
  background: #fff;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  box-shadow: var(--jc-shadow-lg);
}

.user-menu-id {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .7rem .75rem .8rem;
  border-bottom: 1px solid var(--jc-steel-200);
  margin-bottom: .35rem;
}
.user-menu-id-text { min-width: 0; }
.user-menu-id-text strong {
  display: block;
  font-family: var(--jc-display);
  font-size: 1rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--jc-maroon);
}
.user-menu-id-text span {
  display: block;
  overflow: hidden;
  font-size: .8125rem;
  color: var(--jc-steel-500);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-menu-item {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .55rem .75rem;
  border-radius: 10px;
  color: var(--jc-steel-800);
  text-decoration: none;
  transition: background-color .18s ease, color .18s ease;
}
.user-menu-item:hover,
.user-menu-item:focus-visible { background: var(--jc-maroon-50); color: var(--jc-maroon); }
.user-menu-item.is-danger:hover,
.user-menu-item.is-danger:focus-visible { background: var(--jc-crimson-50); color: #8A1513; }

.user-menu-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  border-radius: 8px;
  background: var(--jc-steel-100);
  color: var(--jc-maroon-700);
}
.user-menu-item:hover .user-menu-icon { background: #fff; color: var(--jc-crimson); }
.user-menu-item.is-danger .user-menu-icon { color: #8A1513; }

.user-menu-label {
  min-width: 0;
  font-family: var(--jc-display);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  line-height: 1.2;
}
.user-menu-label span {
  display: block;
  font-family: var(--jc-sans);
  font-size: .78rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--jc-steel-500);
}

/* Drawer variant — same vocabulary, full width, no popup. */
.drawer-id {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .8rem;
  margin-bottom: .75rem;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  background: var(--jc-maroon-50);
  text-decoration: none;
}
.drawer-id-text { min-width: 0; flex: 1 1 auto; }
.drawer-id-text strong {
  display: block;
  font-family: var(--jc-display);
  font-size: 1.05rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--jc-maroon);
}
.drawer-id-text span {
  display: block;
  overflow: hidden;
  font-size: .8125rem;
  color: var(--jc-steel-500);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drawer-account {
  margin: 0 0 1.75rem;
  padding: 0;
  list-style: none;
}
.drawer-account .user-menu-item { padding: .5rem .4rem; }

/* --------------------------------------------------------------------------
   Home hero slider

   The slides were position:absolute, so none of them contributed any height
   and the section stayed pinned at its min-height (560px on a phone). The
   copy on a narrow screen measures ~440–500px on top of 96px of padding, so
   it ran past the bottom of the section and sat on the dots and the prev/next
   buttons — at 360px the CTA buttons were physically on top of the arrows.

   Stacking the slides in a single grid cell puts them back in flow: the row
   is as tall as the TALLEST slide, so the section grows to fit whichever one
   needs it and the height does not jump as the carousel rotates. From md up
   the min-heights still dominate, so the desktop hero is unchanged.
   -------------------------------------------------------------------------- */

[data-hero] { display: grid; grid-template-columns: 1fr; }

[data-hero] .hero-slide {
  position: relative;
  grid-area: 1 / 1;
  inset: auto;
}

/* Below md the hero is content-sized, so the copy needs its own clearance
   over the control strip (48px buttons pinned 32px off the bottom). */
@media (max-width: 767.98px) {
  [data-hero] .hero-slide > .container {
    padding-top: 3.5rem;
    padding-bottom: 7rem;
  }
}

/* --------------------------------------------------------------------------
   Privacy consent banner (first visit, per device)
   -------------------------------------------------------------------------- */

#jcConsent {
  position: fixed;
  z-index: 120;
  left: .75rem;
  right: .75rem;
  bottom: .75rem;
  max-width: 34rem;
  padding: 1.1rem 1.15rem;
  border-radius: 16px;
  background: #fff;
  border: 1px solid var(--jc-steel-200);
  box-shadow: var(--jc-shadow-lg);
  animation: jcConsentIn .45s cubic-bezier(.22, 1, .36, 1) both;
}
@media (min-width: 640px) { #jcConsent { left: 1.25rem; bottom: 1.25rem; right: auto; } }
@keyframes jcConsentIn { from { opacity: 0; transform: translateY(18px); } }

#jcConsent h2 {
  margin: 0 0 .35rem;
  font-family: var(--jc-display);
  font-size: 1.25rem;
  text-transform: uppercase;
  color: var(--jc-maroon);
}
#jcConsent p { margin: 0; font-size: .9rem; line-height: 1.55; color: var(--jc-steel-600); }
#jcConsent .jc-consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .9rem;
}
#jcConsent a.jc-consent-link {
  font-size: .8125rem;
  color: var(--jc-crimson);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.jc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .6rem 1.1rem;
  border: 0;
  border-radius: 10px;
  font-family: var(--jc-display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform .2s ease, background .2s ease, color .2s ease, box-shadow .2s ease;
}
.jc-btn-solid {
  background: linear-gradient(135deg, var(--jc-crimson), var(--jc-red-deep));
  color: #fff;
  box-shadow: 0 6px 18px -8px rgba(144, 26, 29, .7);
}
.jc-btn-solid:hover { transform: translateY(-1px); }
.jc-btn-quiet {
  background: var(--jc-steel-100);
  color: var(--jc-maroon);
}
.jc-btn-quiet:hover { background: var(--jc-steel-200); }
.jc-btn-outline {
  background: #fff;
  color: var(--jc-maroon);
  box-shadow: inset 0 0 0 2px var(--jc-steel-200);
}
.jc-btn-outline:hover { box-shadow: inset 0 0 0 2px var(--jc-crimson); color: var(--jc-crimson); }
.jc-btn-sm { padding: .4rem .75rem; font-size: .875rem; border-radius: 8px; }
.jc-btn-danger { background: #fff; color: #B01B1A; box-shadow: inset 0 0 0 2px #F7C8C7; }
.jc-btn-danger:hover { background: #B01B1A; color: #fff; box-shadow: none; }
.jc-btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; }

/* --------------------------------------------------------------------------
   Ask Coach — the site-wide launcher

   The bottom-right corner is already busy: the accessibility button sits at
   bottom 1.25rem / right 1.25rem (3.5rem wide, 4rem from md up) and the
   back-to-top button stacks above it. So the launcher is placed to the LEFT
   of the accessibility button rather than on top of it.
   -------------------------------------------------------------------------- */

.ask-launcher {
  position: fixed;
  z-index: 40;
  bottom: 1.25rem;
  right: calc(1.25rem + 3.5rem + .6rem);
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .7rem 1rem;
  border-radius: 999px;
  background: linear-gradient(135deg, #D42725, #901A1D);
  color: #fff;
  font-family: var(--jc-display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  box-shadow: 0 10px 28px -12px rgba(42, 8, 23, .75);
  transition: transform .25s ease, box-shadow .25s ease;
}
.ask-launcher:hover {
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 16px 34px -14px rgba(42, 8, 23, .85);
}
.ask-launcher svg { width: 1.25rem; height: 1.25rem; flex: none; }

/* On a narrow screen the label is dropped, leaving a round icon button. */
.ask-launcher-label { display: none; }

@media (min-width: 640px) {
  .ask-launcher-label { display: block; }
}
@media (min-width: 768px) {
  .ask-launcher { bottom: 1.75rem; right: calc(1.75rem + 4rem + .6rem); }
}

/* --------------------------------------------------------------------------
   Ask Coach — chat transcript
   -------------------------------------------------------------------------- */

.ask-shell {
  display: flex;
  flex-direction: column;
  min-height: 60vh;
  background: #fff;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  box-shadow: var(--jc-shadow);
  overflow: hidden;
}

.ask-log {
  flex: 1 1 auto;
  padding: 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  overflow-y: auto;
  max-height: 60vh;
  scroll-behavior: smooth;
}

.ask-msg { display: flex; gap: .7rem; max-width: 100%; }
.ask-msg-user { flex-direction: row-reverse; }

.ask-avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--jc-maroon);
  color: #fff;
}
.ask-msg-user .ask-avatar { background: var(--jc-steel-300); color: var(--jc-steel-800); }

.ask-bubble {
  flex: 0 1 auto;
  max-width: min(46rem, 85%);
  padding: .8rem 1rem;
  border-radius: 14px;
  background: var(--jc-chalk);
  border: 1px solid var(--jc-steel-200);
  font-size: .97rem;
  line-height: 1.6;
  color: var(--jc-steel-800);
}
.ask-msg-user .ask-bubble {
  background: var(--jc-maroon);
  border-color: var(--jc-maroon);
  color: #fff;
}
.ask-bubble p { margin: 0 0 .65rem; }
.ask-bubble p:last-child { margin-bottom: 0; }
.ask-bubble blockquote {
  margin: 0 0 .7rem;
  padding: .2rem 0 .2rem .9rem;
  border-left: 3px solid var(--jc-crimson);
  color: var(--jc-steel-600);
  font-style: italic;
}

/* Citation + product-link card under an answer */
.ask-cite {
  margin-top: .8rem;
  padding-top: .7rem;
  border-top: 1px dashed var(--jc-steel-300);
  font-size: .85rem;
}
.ask-cite-label {
  font-family: var(--jc-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--jc-steel-500);
}
.ask-source {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-top: .4rem;
}
.ask-source strong { color: var(--jc-maroon); }

.ask-buy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin-top: .75rem;
  padding: .7rem;
  border-radius: 12px;
  background: var(--jc-crimson-50);
  border: 1px solid #F7C8C7;
}
.ask-buy img {
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 8px;
  object-fit: cover;
}
.ask-buy-text { flex: 1 1 10rem; min-width: 0; font-size: .85rem; }
.ask-buy-text a { font-weight: 600; color: var(--jc-maroon); }

.ask-form {
  border-top: 1px solid var(--jc-steel-200);
  padding: .9rem 1rem;
  background: var(--jc-chalk);
}
.ask-input-row { display: flex; gap: .55rem; align-items: flex-end; }
.ask-input-row textarea {
  flex: 1 1 auto;
  min-height: 2.9rem;
  max-height: 10rem;
  resize: vertical;
  padding: .7rem .9rem;
  border: 1px solid var(--jc-steel-300);
  border-radius: 10px;
  font: inherit;
  font-size: .97rem;
  background: #fff;
}
.ask-input-row textarea:focus {
  outline: none;
  border-color: var(--jc-crimson);
  box-shadow: 0 0 0 4px rgba(212, 39, 37, .18);
}

.ask-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.ask-chip {
  padding: .35rem .7rem;
  border: 1px solid var(--jc-steel-200);
  border-radius: 999px;
  background: #fff;
  font-size: .8125rem;
  color: var(--jc-steel-600);
  cursor: pointer;
  transition: border-color .2s, color .2s;
}
.ask-chip:hover { border-color: var(--jc-crimson); color: var(--jc-crimson); }

.ask-typing { display: inline-flex; gap: .25rem; align-items: center; }
.ask-typing i {
  width: .4rem;
  height: .4rem;
  border-radius: 50%;
  background: var(--jc-steel-400);
  animation: askBlink 1.1s infinite ease-in-out;
}
.ask-typing i:nth-child(2) { animation-delay: .15s; }
.ask-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes askBlink { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }

/* --------------------------------------------------------------------------
   Playbook Finder — the 2-minute quiz
   -------------------------------------------------------------------------- */

.quiz-progress {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: 1.5rem;
}
.quiz-step {
  flex: 1 1 0;
  height: .3rem;
  border-radius: 999px;
  background: var(--jc-steel-200);
  overflow: hidden;
}
.quiz-step.is-done { background: var(--jc-crimson); }
.quiz-step.is-current { background: linear-gradient(90deg, var(--jc-crimson) 50%, var(--jc-steel-200) 50%); }

.quiz-options {
  display: grid;
  gap: .7rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .quiz-options { grid-template-columns: 1fr 1fr; } }

.quiz-option { position: relative; display: block; cursor: pointer; }
.quiz-option input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}
.quiz-face {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  height: 100%;
  padding: 1rem;
  border: 2px solid var(--jc-steel-200);
  border-radius: 12px;
  background: #fff;
  transition: border-color .2s, background .2s, transform .2s;
}
.quiz-option:hover .quiz-face { border-color: #EBA9A8; transform: translateY(-1px); }
.quiz-option input:checked + .quiz-face {
  border-color: var(--jc-crimson);
  background: var(--jc-crimson-50);
}
.quiz-option input:focus-visible + .quiz-face {
  outline: 3px solid var(--jc-crimson);
  outline-offset: 2px;
}
.quiz-face-title {
  display: block;
  font-family: var(--jc-display);
  font-size: 1.1rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--jc-maroon);
}
.quiz-face-note { display: block; font-size: .85rem; color: var(--jc-steel-500); }
.quiz-tick {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 1.35rem;
  height: 1.35rem;
  margin-left: auto;
  border: 2px solid var(--jc-steel-300);
  border-radius: 50%;
  color: transparent;
}
.quiz-option input:checked + .quiz-face .quiz-tick {
  background: var(--jc-crimson);
  border-color: var(--jc-crimson);
  color: #fff;
}

/* Recommendation ranking badge */
.rec-rank {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--jc-maroon);
  color: #fff;
  font-family: var(--jc-display);
  font-size: 1rem;
  font-weight: 700;
}
.rec-why {
  margin-top: .5rem;
  padding-left: .85rem;
  border-left: 3px solid var(--jc-crimson);
  font-size: .9rem;
  color: var(--jc-steel-600);
}

/* --------------------------------------------------------------------------
   Forum
   -------------------------------------------------------------------------- */

.forum-board {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding: 1.1rem;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  background: #fff;
  box-shadow: var(--jc-shadow);
  transition: transform .2s, box-shadow .2s;
}
.forum-board:hover { transform: translateY(-2px); box-shadow: var(--jc-shadow-lg); }
.forum-board-icon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 12px;
  background: var(--jc-maroon-50);
  color: var(--jc-maroon);
}

.forum-thread-row {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1rem;
  align-items: baseline;
  padding: .9rem 0;
  border-bottom: 1px solid var(--jc-steel-200);
}
.forum-thread-row:last-child { border-bottom: 0; }
.forum-thread-title {
  flex: 1 1 18rem;
  font-family: var(--jc-display);
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--jc-maroon);
}
.forum-thread-title a:hover { color: var(--jc-crimson); }
.forum-meta { font-size: .8125rem; color: var(--jc-steel-500); }

.forum-post {
  padding: 1.1rem;
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  background: #fff;
}
.forum-post-coach {
  border-color: #F0C9C8;
  background: linear-gradient(180deg, var(--jc-crimson-50), #fff 60%);
}
.forum-post-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-bottom: .6rem;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--jc-steel-200);
}
.forum-body { font-size: .97rem; line-height: 1.7; color: var(--jc-steel-700, #4A5057); }
.forum-body p { margin: 0 0 .9rem; }
.forum-body p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Speaking — availability calendar
   -------------------------------------------------------------------------- */

.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: .25rem;
}
.cal-dow {
  padding: .35rem 0;
  text-align: center;
  font-family: var(--jc-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--jc-steel-400);
}
.cal-day {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: 9px;
  border: 1px solid var(--jc-steel-200);
  background: #fff;
  font-size: .85rem;
  font-weight: 600;
  color: var(--jc-steel-600);
}
.cal-day-empty { border: 0; background: transparent; }
.cal-day-past { background: var(--jc-steel-100); color: var(--jc-steel-400); border-style: dashed; }
.cal-available { background: var(--jc-ok-bg); border-color: #A7F3D0; color: #065F46; }
.cal-tentative { background: var(--jc-warn-bg); border-color: #FDE68A; color: #92400E; }
.cal-booked    { background: var(--jc-crimson-50); border-color: #F7C8C7; color: #8A1513; }
.cal-blocked   { background: var(--jc-steel-200); color: var(--jc-steel-500); }
a.cal-day:hover { outline: 2px solid var(--jc-crimson); outline-offset: 1px; }

.cal-key { display: flex; flex-wrap: wrap; gap: .75rem; font-size: .8125rem; color: var(--jc-steel-500); }
.cal-key span { display: inline-flex; align-items: center; gap: .35rem; }
.cal-key i {
  width: .8rem;
  height: .8rem;
  border-radius: 4px;
  border: 1px solid var(--jc-steel-200);
}

/* --------------------------------------------------------------------------
   Online eBook reader
   -------------------------------------------------------------------------- */

.reader-frame {
  width: 100%;
  height: min(80vh, 900px);
  border: 1px solid var(--jc-steel-200);
  border-radius: var(--jc-radius);
  background: var(--jc-steel-100);
}
.reader-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .6rem;
  padding: .7rem 1rem;
  border: 1px solid var(--jc-steel-200);
  border-bottom: 0;
  border-radius: var(--jc-radius) var(--jc-radius) 0 0;
  background: #fff;
}
.reader-bar + .reader-frame { border-radius: 0 0 var(--jc-radius) var(--jc-radius); }

/* ==========================================================================
   Missing component layer
   ==========================================================================

   app.css was compiled BEFORE five component families were added to
   build/tailwind.src.css, so the badges, filter chips, format toggle, shop
   filter panel and payment picker shipped unstyled. There is no longer a Node
   toolchain to rebuild that file, so they are written out here by hand — the
   same declarations Tailwind would have emitted from those @apply rules, with
   the palette read back out of the compiled file:

     maroon-900 #2A0817 · maroon-800 #380B1F · maroon-50 #F7EEF2
     crimson-500 #D42725 · crimson-600 #C42423 · crimson-50 #FDF2F2
     steel-100 #F2F2F3 · steel-200 #E3E3E5 · steel-300 #D6D6D6
     steel-400 #A9A9AD · steel-500 #7C7C82 · steel-600 #5A5A60
   -------------------------------------------------------------------------- */

:root {
  --jc-font-display: "Barlow Condensed", "Barlow Condensed Fallback", "Arial Narrow", Arial, sans-serif;
  --jc-m900: #2A0817;
  --jc-m800: #380B1F;
  --jc-m50: #F7EEF2;
  --jc-c500: #D42725;
  --jc-c600: #C42423;
  --jc-c50: #FDF2F2;
  --jc-s100: #F2F2F3;
  --jc-s200: #E3E3E5;
  --jc-s300: #D6D6D6;
  --jc-s400: #A9A9AD;
  --jc-s500: #7C7C82;
  --jc-s600: #5A5A60;
  --jc-grad: linear-gradient(135deg, #D42725, #901A1D);
  --jc-card-shadow: 0 1px 2px rgba(42, 8, 23, .06), 0 10px 26px -14px rgba(42, 8, 23, .22);
}

/* ---------- Badges ---------- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .25rem .625rem;
  border-radius: 9999px;
  font-family: var(--jc-font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  line-height: 1.3;
}
.badge-green  { background: #ECFDF5; color: #047857; }
.badge-amber  { background: #FFFBEB; color: #B45309; }
.badge-red    { background: var(--jc-c50); color: #A91F20; }
.badge-steel  { background: var(--jc-s100); color: var(--jc-s600); }
.badge-maroon { background: var(--jc-m50); color: var(--jc-m800); }

/* ---------- Removable filter chip ---------- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .25rem .75rem;
  border: 1px solid var(--jc-s200);
  border-radius: 9999px;
  background: #fff;
  font-size: 13px;
  font-weight: 600;
  color: var(--jc-m800);
  transition: border-color .2s, color .2s;
}
.chip:hover { border-color: #EC8683; color: var(--jc-c600); }

/* ---------- Format toggle (eBook / Print) ----------
   One product, two formats. The radio is visually hidden and its sibling
   label is styled, so the control works with no JavaScript and the price is
   printed on each option. */

.fmt-switch {
  display: grid;
  gap: .375rem;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  padding: .25rem;
  border-radius: .75rem;
  background: var(--jc-s100);
}
.fmt-option { position: relative; cursor: pointer; }
.fmt-option > input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.fmt-face {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .125rem;
  padding: .5rem;
  border-radius: .5rem;
  text-align: center;
  transition: background .2s, box-shadow .2s;
}
.fmt-name {
  font-family: var(--jc-font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--jc-s500);
  transition: color .2s;
}
.fmt-price {
  font-family: var(--jc-font-display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
  color: var(--jc-m900);
}
.fmt-option > input:checked ~ .fmt-face {
  background: #fff;
  box-shadow: 0 1px 2px rgba(42, 8, 23, .08);
}
.fmt-option > input:checked ~ .fmt-face .fmt-name { color: var(--jc-c600); }
.fmt-option > input:focus-visible ~ .fmt-face {
  outline: 2px solid var(--jc-c500);
  outline-offset: 1px;
}
.fmt-option > input:disabled ~ .fmt-face { cursor: not-allowed; opacity: .4; }
.fmt-option:hover > input:not(:checked):not(:disabled) ~ .fmt-face { background: rgba(255, 255, 255, .6); }

/* Larger variant for the product detail page */
.fmt-switch-lg .fmt-face { gap: .25rem; padding: .75rem 1rem; }
.fmt-switch-lg .fmt-name { font-size: 12px; }
.fmt-switch-lg .fmt-price { font-size: 1.25rem; }

/* ---------- Shop filters ----------
   Mobile first: the panel is a <details> that starts collapsed on a phone.
   A <details> cannot be forced open by CSS, so from lg up its summary is made
   inert and the hidden content is displayed anyway — a permanent sidebar on
   desktop, a disclosure on mobile, with no JavaScript. */

.filter-panel > summary { list-style: none; cursor: pointer; }
.filter-panel > summary::-webkit-details-marker,
.filter-panel > summary::marker { display: none; content: ""; }

@media (min-width: 1024px) {
  /* Displaying the form is no longer enough on its own: a closed <details>
     now keeps its children in the UA's ::details-content slot, which carries
     content-visibility:hidden. The form was still being laid out — invisible,
     outside the panel's own box, and sitting on top of the product grid — so
     the slot has to be opened as well. app.js sets .open as the fallback for
     browsers without ::details-content. */
  .filter-panel::details-content {
    content-visibility: visible;
    block-size: auto;
  }
  .filter-panel:not([open]) > form { display: block; }
  .filter-panel > summary { pointer-events: none; }
}

.filter-group {
  padding: 1rem 0;
  border-bottom: 1px solid var(--jc-s200);
}
.filter-group:last-child { border-bottom: 0; }

.filter-title {
  margin-bottom: .75rem;
  font-family: var(--jc-font-display);
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--jc-m900);
}

.filter-check {
  display: flex;
  align-items: center;
  gap: .625rem;
  padding: .25rem 0;
  font-size: 15px;
  color: var(--jc-s600);
  cursor: pointer;
  transition: color .2s;
}
.filter-check:hover { color: var(--jc-c600); }
.filter-check input {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  border-radius: .25rem;
  border: 1px solid var(--jc-s300);
  accent-color: #D42725;
}
.filter-count { margin-left: auto; font-size: 12px; color: var(--jc-s400); }

/* ---------- Payment method picker ----------
   Same hidden-radio pattern as the format switch: one tap target per method,
   with the selected state driven by :checked. */

.pay-option { display: block; cursor: pointer; }
.pay-option > input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.pay-face {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
  border: 2px solid var(--jc-s200);
  border-radius: .75rem;
  background: #fff;
  transition: border-color .2s, background .2s, box-shadow .2s;
}
.pay-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: .5rem;
  background: var(--jc-s100);
  color: #5B1227;
  transition: background .2s, color .2s;
}
.pay-check {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid var(--jc-s300);
  border-radius: 9999px;
  color: transparent;
  transition: border-color .2s, background .2s, color .2s;
}
.pay-option:hover > input:not(:checked) ~ .pay-face { border-color: #EC8683; }
.pay-option > input:checked ~ .pay-face {
  border-color: var(--jc-c500);
  background: rgba(253, 242, 242, .6);
  box-shadow: 0 1px 2px rgba(42, 8, 23, .08);
}
.pay-option > input:checked ~ .pay-face .pay-icon { background-image: var(--jc-grad); color: #fff; }
.pay-option > input:checked ~ .pay-face .pay-check {
  border-color: var(--jc-c500);
  background: var(--jc-c500);
  color: #fff;
}
.pay-option > input:focus-visible ~ .pay-face {
  outline: 2px solid var(--jc-c500);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   Utility top-up

   app.css is a *purged* Tailwind build: it contains only the utilities the
   templates used at build time. Pages written after that build need a handful
   more, and there is no longer a Node toolchain to regenerate the file — so
   they are declared here, by hand, with the exact values Tailwind would have
   emitted. Keep this list short and alphabetical-ish; prefer a class that
   already exists in app.css whenever one will do.
   -------------------------------------------------------------------------- */

/* spacing — classes the existing templates use that the build never emitted */
.gap-0 { gap: 0; }
.p-10 { padding: 2.5rem; }
.pt-7 { padding-top: 1.75rem; }
.pb-5 { padding-bottom: 1.25rem; }
.pl-10 { padding-left: 2.5rem; }
.pr-1 { padding-right: .25rem; }
.max-h-72 { max-height: 18rem; }
.min-w-\[220px\] { min-width: 220px; }
.text-\[14px\] { font-size: 14px; }
.cursor-default { cursor: default; }
.\!pt-0 { padding-top: 0 !important; }

/* colours the existing templates use that the build never emitted */
.bg-amber-100 { background-color: #FEF3C7; }
.text-amber-900 { color: #78350F; }
.border-amber-300 { border-color: #FCD34D; }
.bg-emerald-600 { background-color: #059669; }
.text-emerald-800 { color: #065F46; }
.border-emerald-300 { border-color: #6EE7B7; }
.text-crimson-200 { color: #F6CBCA; }
/* The shop hero asks for the brand gradient by its token name. */
.bg-brand-gradient { background-image: linear-gradient(135deg, #D42725, #901A1D); }

@media (min-width: 640px) {
  .sm\:p-6 { padding: 1.5rem; }
  .sm\:p-7 { padding: 1.75rem; }
  .sm\:p-10 { padding: 2.5rem; }
  .sm\:p-14 { padding: 3.5rem; }
}
@media (min-width: 768px) {
  .md\:p-6 { padding: 1.5rem; }
  .md\:col-span-9 { grid-column: span 9 / span 9; }
}
@media (min-width: 1024px) {
  .lg\:cursor-default { cursor: default; }
  .lg\:pointer-events-none { pointer-events: none; }
}

/* spacing */
.h-2 { height: .5rem; }
.w-2 { width: .5rem; }
.h-2\.5 { height: .625rem; }
.w-2\.5 { width: .625rem; }
.h-px { height: 1px; }
.py-2\.5 { padding-top: .625rem; padding-bottom: .625rem; }
.px-3\.5 { padding-left: .875rem; padding-right: .875rem; }
.pb-3 { padding-bottom: .75rem; }
.pb-4 { padding-bottom: 1rem; }
.pt-2 { padding-top: .5rem; }
.pl-5 { padding-left: 1.25rem; }
.mb-1 { margin-bottom: .25rem; }
.mb-1\.5 { margin-bottom: .375rem; }
.mb-2 { margin-bottom: .5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-10 { margin-bottom: 2.5rem; }
.mt-16 { margin-top: 4rem; }
.ml-auto { margin-left: auto; }
.gap-0\.5 { gap: .125rem; }
.space-y-5 > :not([hidden]) ~ :not([hidden]) { margin-top: 1.25rem; }
.space-y-8 > :not([hidden]) ~ :not([hidden]) { margin-top: 2rem; }

/* position */
.right-1 { right: .25rem; }
.right-2 { right: .5rem; }
.top-1\.5 { top: .375rem; }
.top-2 { top: .5rem; }
.left-1\/2 { left: 50%; }
.-translate-x-1\/2 { --tw-translate-x: -50%; transform: translate(-50%, var(--tw-translate-y, 0)); }

/* layout */
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.basis-full { flex-basis: 100%; }
.flex-none { flex: none; }
.justify-end { justify-content: flex-end; }
.max-w-5xl { max-width: 64rem; }
.max-w-6xl { max-width: 72rem; }
.max-w-none { max-width: none; }
.list-disc { list-style-type: disc; }
.list-inside { list-style-position: inside; }
.whitespace-pre-line { white-space: pre-line; }
.whitespace-nowrap { white-space: nowrap; }
.break-words { overflow-wrap: break-word; }
.tabular-nums { font-variant-numeric: tabular-nums; }
.italic { font-style: italic; }
.font-normal { font-weight: 400; }
.resize-y { resize: vertical; }
.appearance-none { appearance: none; }
.cursor-not-allowed { cursor: not-allowed; }
.select-none { user-select: none; }
.shadow-md { box-shadow: 0 4px 6px -1px rgba(24, 6, 14, .1), 0 2px 4px -2px rgba(24, 6, 14, .1); }
.rounded-b-2xl { border-bottom-left-radius: 1rem; border-bottom-right-radius: 1rem; }

@media (min-width: 640px) {
  .sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .sm\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .sm\:flex-row { flex-direction: row; }
  .sm\:items-center { align-items: center; }
}
@media (min-width: 768px) {
  .md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .lg\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .lg\:col-span-6 { grid-column: span 6 / span 6; }
  .lg\:col-span-9 { grid-column: span 9 / span 9; }
}

/* status colours — used by badges and flashes outside the brand ramp */
.bg-emerald-50 { background-color: #ECFDF5; }
.bg-emerald-500 { background-color: #10B981; }
.text-emerald-600 { color: #059669; }
.text-emerald-700 { color: #047857; }
.border-emerald-200 { border-color: #A7F3D0; }
.bg-amber-50 { background-color: #FFFBEB; }
.text-amber-700 { color: #B45309; }
.border-amber-200 { border-color: #FDE68A; }
.bg-blue-50 { background-color: #EFF6FF; }
.text-blue-700 { color: #1D4ED8; }
.border-blue-200 { border-color: #BFDBFE; }
.bg-crimson-50\/50 { background-color: rgba(253, 242, 242, .5); }
.hover\:bg-crimson-50\/50:hover { background-color: rgba(253, 242, 242, .5); }
.hover\:text-crimson-300:hover { color: #EBA9A8; }
.ring-white { --tw-ring-color: #fff; }

/* --------------------------------------------------------------------------
   Print — receipts and order sheets
   -------------------------------------------------------------------------- */

@media print {
  .jc-no-print { display: none !important; }
  .jc-panel { box-shadow: none; border-color: #BBB; }
}
