/* Floor Is Lava Class. Shared stylesheet, linked by every page. */

/* ---------- Tokens ---------- */
:root {
  --lava: #ff4d1c;
  --lava-deep: #d62828;
  --ember: #ffb627;
  --rock: #1f1b1a;
  --rock-soft: #3d3634;
  --muted: #6b5f58;
  --cream: #fff6ec;
  --card: #ffffff;
  --line: #efe2d4;

  --radius: 18px;
  --radius-pill: 999px;
  --shadow: 0 6px 24px rgba(31, 27, 26, 0.09);
  --shadow-lift: 0 12px 34px rgba(214, 40, 40, 0.18);
  --wrap: 1080px;
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--rock);
  font-family: "Nunito", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 18px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: "Fredoka", "Nunito", system-ui, sans-serif;
  line-height: 1.15;
  margin: 0 0 0.4em;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(2.4rem, 6vw, 4rem); font-weight: 600; }
h2 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); font-weight: 600; }
h3 { font-size: 1.3rem; font-weight: 600; }

p { margin: 0 0 1em; }

a { color: var(--lava-deep); }

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

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 24px;
}

section { padding: 72px 0; }

/* Section descriptions. These are the main read for a skimming parent, so they sit
   clearly above body size rather than just above it. */
.lede { font-size: clamp(1.2rem, 1.9vw, 1.35rem); color: var(--muted); max-width: 58ch; }

.center { text-align: center; }
.center .lede { margin-left: auto; margin-right: auto; }

/* Unconfirmed copy. Marked so it cannot ship by accident.
   Remove every .tbd wrapper before the first production push.
   Enforcement is the grep in the pre-push checklist, not this styling, so the
   dark-background variant below is free to be quieter without losing the safety net. */
.tbd {
  background: #fff3bf;
  border-bottom: 2px dashed #e0a800;
  padding: 0 2px;
}

/* On the dark footer and CTA band a highlighter block reads as a glitch.
   Same signal, carried by an ember underline instead of a fill. */
.site-footer .tbd,
.band .tbd {
  background: none;
  color: var(--ember);
  border-bottom: 1px dashed var(--ember);
  padding: 0;
}
.site-footer a.tbd:hover { color: #fff; border-bottom-color: #fff; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  background: var(--lava);
  color: #fff;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  text-decoration: none;
  padding: 15px 32px;
  border-radius: var(--radius-pill);
  border: 0;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
  box-shadow: var(--shadow-lift);
}
.btn:hover { background: var(--lava-deep); transform: translateY(-2px); }

.btn-ghost {
  background: transparent;
  color: var(--rock);
  border: 2px solid var(--rock);
  box-shadow: none;
}
.btn-ghost:hover { background: var(--rock); color: #fff; }

.btn-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 28px;
}
/* Matches .center on an ancestor OR on the row itself. The hero and 404 put it on
   the row, so the descendant selector alone silently left them flush left. */
.center .btn-row,
.btn-row.center { justify-content: center; }

/* ---------- Header / nav ---------- */
/* Opaque on purpose. This used to be rgba(...,0.92) plus backdrop-filter: blur(8px),
   which made scrolling sluggish: a sticky element cannot cache a backdrop blur, so the
   browser re-sampled and re-blurred the area behind the header on every scroll frame.
   At 92% opacity the blur was acting on almost nothing anyway, so it cost real frames
   for an effect that was not visible. Do not reintroduce it. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--cream);
  border-bottom: 1px solid var(--line);
}

.nav-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 24px;
  max-width: var(--wrap);
  margin: 0 auto;
}

/* Register lives here rather than inside .nav-links so it stays visible when the
   menu collapses. A primary CTA hidden behind a hamburger is a CTA nobody presses. */
.nav-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}
.nav-btn { font-size: 0.95rem; padding: 10px 22px; color: #fff; }
.nav-btn:hover { color: #fff; }

/* The wordmark must always be visible, at every width. It is not allowed to wrap and
   it is not allowed to hide, so everything else in the bar gives way instead: the mark,
   the gaps, the button padding and the toggle padding all step down on small screens,
   and the wordmark itself scales with the viewport.
   Worst case, a 320px phone, after the 360px block below:
     320 - 32 (nav padding) - 32 (toggle) - 8 (actions gap)
         - 87 (Register) - 10 (nav gap) - 28 (mark and its gap) = 123px for the text
   "Floor Is Lava Class" is roughly 10em of Fredoka 600, and 3.4vw at 320px is about
   10.9px, so it needs about 109px. It fits with room to spare. */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Fredoka", sans-serif;
  font-size: clamp(1rem, 3.2vw, 1.2rem);
  font-weight: 600;
  white-space: nowrap;
  color: var(--rock);
  text-decoration: none;
}
.brand svg { width: 30px; height: 30px; flex: none; }

.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links a {
  color: var(--rock);
  text-decoration: none;
  font-weight: 600;
  font-size: 1rem;
}
/* :not(.btn) matters. Without it this rule also hits the Sign Up button and turns its
   text --lava-deep, the exact color .btn:hover sets as the background, so the label
   vanished into the fill. It outranks .btn:hover on specificity, so the button cannot
   defend itself; the exclusion has to live here. */
.nav-links a:not(.btn):hover { color: var(--lava-deep); }

.nav-toggle {
  display: none;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 8px;
  color: var(--rock);
}
.nav-toggle svg { width: 26px; height: 26px; }

/* ---------- Hero ---------- */
/* Padding is in vh so the hero shrinks on short screens instead of pushing everything
   below it off the fold. The goal is that the dark .pillars strip is always partly
   visible on landing: a hard color edge at the bottom of the screen is what tells a
   visitor the page scrolls. Raising these numbers will eat that cue. */
.hero {
  background:
    radial-gradient(900px 420px at 50% -10%, rgba(255, 182, 39, 0.35), transparent 70%),
    linear-gradient(180deg, #fff6ec 0%, #ffe9d6 100%);
  padding: clamp(38px, 6vh, 64px) 0 clamp(42px, 6.5vh, 70px);
  text-align: center;
  position: relative;
  overflow: hidden;
}
.hero h1 { font-size: clamp(2.3rem, 5.4vw, 3.4rem); margin-bottom: 0.3em; }
.hero h1 span { color: var(--lava); }
.hero .lede { margin: 0 auto; font-size: clamp(1.3rem, 2.6vw, 1.55rem); color: var(--rock); }
.hero .btn-row { margin-top: 22px; }

.hero-rule {
  height: 8px;
  background: linear-gradient(90deg, var(--ember), var(--lava), var(--lava-deep));
}

/* ---------- Pillars ----------
   The three words the whole class is about, sitting directly under the hero so they
   are the first thing read after the pitch. Dark, to frame the hero against the cream
   section below it. Not a <section>, so it does not affect the cream/white alternation. */
.pillars {
  background: var(--rock);
  padding: 20px 0;
}

.pillars .wrap {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px clamp(26px, 6vw, 64px);
}

.pillars span {
  position: relative;
  color: #fff;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: clamp(1.05rem, 2.4vw, 1.55rem);
  letter-spacing: 0.01em;
}

/* Lava dot between words. Sits in the gap, so it is attached to the second word of
   each pair rather than drawn as a separate element. */
.pillars span + span::before {
  content: "";
  position: absolute;
  left: calc(-1 * clamp(13px, 3vw, 32px));
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--lava);
}

/* ---------- Cards ---------- */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 22px;
  margin-top: 44px;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 30px 26px;
  box-shadow: var(--shadow);
}
.card h3 { margin-bottom: 8px; }
.card p { color: var(--muted); margin: 0; font-size: 1.05rem; }

.card-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: var(--radius-pill);
  background: var(--lava);
  color: #fff;
  font-family: "Fredoka", sans-serif;
  font-weight: 600;
  margin-bottom: 14px;
}

/* ---------- Steps ----------
   Four across, joined by one line, for the rules. Horizontal because these are
   conditions that all hold at once, not a sequence in time. The timeline below is the
   sequence, and keeping the two shapes distinct is the point.
   The marker ring punches a gap in the connecting line, so it has to match the section
   background. This sits on cream. */
.steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  margin-top: 46px;
}

/* Inset by half a column each side so the line spans marker centre to marker centre
   rather than running out past the first and last. */
.steps::before {
  content: "";
  position: absolute;
  top: 24px;
  left: 12.5%;
  right: 12.5%;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--ember), var(--lava), var(--lava-deep));
}

.step { text-align: center; }
.step h3 { font-size: 1.15rem; margin-bottom: 6px; }
.step p { color: var(--muted); margin: 0; font-size: 1.02rem; }

.step-num {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin: 0 auto 16px;
  border-radius: var(--radius-pill);
  background: var(--lava);
  color: #fff;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.2rem;
  box-shadow: 0 0 0 6px var(--cream);
}

/* ---------- Timeline ----------
   Used by the "What a class looks like" section. The marker ring punches a gap in the
   connecting line behind it, so it has to match whatever the section background is.
   It defaults to --cream; a section on white sets --timeline-ring: #fff on itself. */
.timeline {
  position: relative;
  max-width: 700px;
  margin: 44px auto 0;
  text-align: left;
}

.timeline::before {
  content: "";
  position: absolute;
  left: 21px;
  top: 10px;
  bottom: 10px;
  width: 4px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--ember), var(--lava), var(--lava-deep));
}

.timeline-item {
  position: relative;
  padding: 0 0 34px 66px;
}
.timeline-item:last-child { padding-bottom: 0; }

.timeline-item h3 { margin: 8px 0 6px; }
.timeline-item p { color: var(--muted); margin: 0; font-size: 1.05rem; }

.timeline-marker {
  position: absolute;
  left: 0;
  top: 0;
  width: 46px;
  height: 46px;
  border-radius: var(--radius-pill);
  background: var(--lava);
  color: #fff;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 1.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 6px var(--timeline-ring, var(--cream));
}

/* ---------- Legal pages ----------
   Left aligned and on a narrower measure than the marketing sections. This is text to
   be read in sequence rather than skimmed, so it wants ordinary reading ergonomics. */
.legal { max-width: 760px; margin: 0 auto; }
.legal h1 { font-size: clamp(2rem, 4vw, 2.6rem); margin-bottom: 0.2em; }
.legal h2 { font-size: clamp(1.3rem, 2.2vw, 1.6rem); margin-top: 1.9em; }
.legal p, .legal li { color: var(--rock); }
.legal ul { padding-left: 1.2em; margin: 0 0 1em; }
.legal li { margin-bottom: 0.6em; }
.legal-date {
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 2em;
}

/* ---------- Dark CTA band ---------- */
.band {
  background: var(--rock);
  color: #fff;
  text-align: center;
}
.band h2 { color: #fff; }
.band p { color: #d9cfc7; }
.band .lede { color: #d9cfc7; }
/* The global link color is --lava-deep, which is near-black-on-black here. Ember
   reads cleanly against --rock. Any link placed in the band needs this.
   :not(.btn) is required, and this is the third time this exact bug has appeared:
   a bare `.band a` also matches the Sign Up button and outranks .btn on specificity,
   turning its label ember. Scope link colors away from .btn every time. */
.band a:not(.btn) { color: var(--ember); }
.band a:not(.btn):hover { color: #fff; }
.band .btn { color: #fff; }

/* ---------- Form embed ---------- */
/* ---------- Form embed ----------
   A Tally embed needs two third-party round trips in series before anything paints:
   fetch embed.js, and only then let it set the iframe src. Without a placeholder the
   wrapper is simply white for a second or two. min-height reserves the space so the
   page does not jump when the form arrives, and .form-status paints over the top
   until either a postMessage or a guarded load event says the form is there. */
.form-wrapper {
  position: relative;
  min-height: 520px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 8px;
  margin: 36px auto 0;
  max-width: 720px;
}
.form-wrapper iframe { display: block; width: 100%; border: 0; }

/* Top aligned rather than centred, so the spinner sits roughly where the form itself
   begins and the eye does not have to travel when the two swap. */
.form-status {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 0.9rem;
  text-align: center;
  color: var(--muted);
  padding: 2.5rem 1rem 2rem;
}
.form-wrapper.loaded .form-status { display: none; }
.form-status p { margin: 0; }

.form-spinner {
  width: 34px;
  height: 34px;
  border: 3px solid var(--line);
  border-top-color: var(--lava);
  border-radius: var(--radius-pill);
  animation: form-spin 0.9s linear infinite;
}
@keyframes form-spin { to { transform: rotate(360deg); } }

/* A frozen spinner reads as a rendering fault. The text carries the meaning alone. */
@media (prefers-reduced-motion: reduce) { .form-spinner { display: none; } }

/* Only surface the escape hatch once the wait is genuinely unusual. */
.form-fallback { display: none; font-size: 0.95rem; }
.form-wrapper.slow .form-fallback { display: block; }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--rock);
  color: #c9bfb8;
  padding: 52px 0 36px;
  font-size: 0.95rem;
}
.site-footer a { color: #fff; text-decoration: none; }
/* :not(.btn) for the same reason as the nav rule above: without it, the footer CTA
   picks up an underline on hover, which a filled pill button should never have. */
.site-footer a:not(.btn):hover { text-decoration: underline; }

/* Explicit column widths rather than auto-fit. The blurb column carries far more text
   than the other two, and equal thirds left the single-item Contact column stranded in
   its own empty quarter of the footer.
   Both text columns are capped so their lines wrap at a readable measure instead of
   running the full width of a wide monitor. */
.footer-grid {
  display: grid;
  grid-template-columns: 1.3fr 0.9fr 1.3fr;
  gap: 28px 44px;
}
.footer-grid > div:first-child { max-width: 30ch; }
.footer-grid > div:last-child { max-width: 30ch; }
.site-footer h3 {
  color: #fff;
  font-size: 1rem;
  margin-bottom: 10px;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 7px; }
.site-footer p { color: #c9bfb8; }

/* Footer CTA. Smaller than a page button and without the heavy lift shadow, which
   reads as floating debris against the dark background. */
.footer-btn {
  font-size: 0.95rem;
  padding: 11px 24px;
  margin-top: 14px;
  box-shadow: none;
}
.footer-btn:hover { transform: translateY(-1px); }
.footer-bottom {
  border-top: 1px solid #3d3634;
  margin-top: 34px;
  padding-top: 20px;
  text-align: center;
  color: #9a8f87;
  font-size: 0.88rem;
}
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 22px;
  margin: 0 0 12px;
}

/* ---------- Mobile ---------- */
@media (max-width: 900px) {
  body { font-size: 17px; }
  section { padding: 56px 0; }

  /* Explicit columns above would otherwise stay 3-across and crush on a phone. */
  .footer-grid { grid-template-columns: 1fr; gap: 30px; }
  .footer-grid > div:first-child,
  .footer-grid > div:last-child { max-width: none; }

  .timeline::before { left: 17px; }
  .timeline-item { padding-left: 56px; padding-bottom: 28px; }
  .timeline-marker { width: 38px; height: 38px; font-size: 1rem; box-shadow: 0 0 0 5px var(--timeline-ring, var(--cream)); }

  .nav-toggle { display: block; }

  /* Everything here exists to keep the wordmark on screen. These are the numbers the
     .brand comment above does its arithmetic against. */
  .nav-bar { padding: 12px 16px; gap: 10px; }
  .nav-actions { gap: 8px; }
  .brand { gap: 6px; font-size: clamp(0.75rem, 3.4vw, 1.05rem); }
  .brand svg { width: 24px; height: 24px; }
  .nav-btn { font-size: 0.9rem; padding: 9px 16px; }
  .nav-toggle { padding: 6px; }
  .nav-toggle svg { width: 24px; height: 24px; }

  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--cream);
    border-bottom: 1px solid var(--line);
    padding: 8px 24px 20px;
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 13px 0; border-bottom: 1px solid var(--line); }
}

/* The three words wrap onto two lines on a phone, and a separator dot stranded at the
   start of a line reads as a bullet. Drop the dots and let the words breathe instead. */
@media (max-width: 600px) {
  .pillars .wrap { gap: 4px 22px; }
  .pillars span + span::before { display: none; }
}


/* 360px is a common Android width and 320px still exists. One more step down for the
   surrounding furniture, so the wordmark never has to disappear. */
@media (max-width: 360px) {
  .brand svg { width: 22px; height: 22px; }
  .nav-btn { font-size: 0.82rem; padding: 8px 13px; }
  .nav-toggle { padding: 4px; }
}

/* Four columns of prose get too narrow to read well before the 900px nav breakpoint,
   so the steps reflow earlier and on their own terms. The connecting line only means
   anything in a single row, so it goes when the row does. */
@media (max-width: 880px) {
  .steps { grid-template-columns: repeat(2, 1fr); gap: 34px 24px; }
  .steps::before { display: none; }
}
@media (max-width: 520px) {
  .steps { grid-template-columns: 1fr; gap: 30px; }
  .step-num { width: 46px; height: 46px; font-size: 1.1rem; margin-bottom: 12px; }
}
