/* ==========================================================================
   10th Planet Jiu Jitsu Portland
   base.css — design tokens, reset, typography, layout primitives
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* --- Page furniture. The client palette, and nothing else. --- */
  --ink:        #000B1F;   /* deep navy — dark grounds, nav, footer */
  --blue:       #0066FF;   /* the single accent */
  --paper:      #FFFFFF;   /* light ground */
  --mist:       #F0F6FF;   /* tinted light ground */

  /* --- Two derived neutrals. Half-steps only, no new hues. --- */
  --ink-2:      #04122B;   /* banding step above ink */
  --ink-3:      #0A1C3A;   /* card ground on dark */
  --slate:      #5A6B85;   /* body text on light */
  --slate-deep: #1E2E4A;   /* headings on light */

  /* --- Alpha derivations of the palette (no new colors introduced) --- */
  --blue-08:    rgba(0, 102, 255, 0.08);
  --blue-14:    rgba(0, 102, 255, 0.14);
  --blue-24:    rgba(0, 102, 255, 0.24);
  --blue-40:    rgba(0, 102, 255, 0.40);
  --on-ink:     rgba(255, 255, 255, 0.92);
  --on-ink-mid: rgba(214, 228, 250, 0.66);
  --on-ink-dim: rgba(190, 208, 236, 0.44);
  --rule-dark:  rgba(120, 160, 220, 0.16);
  --rule-light: rgba(0, 11, 31, 0.09);

  /* --- Data colors. Schedule legend only. Sourced from the gym's own
         printed class grid, tuned to sit on navy. Never page furniture. --- */
  --lv1:        #00C2FF;   /* Foundations */
  --lv2:        #2FD08A;   /* Integrated Grappling */
  --lv3:        #FF4D5A;   /* Advanced Performance */
  --kids:       #FFC53D;   /* Kids & Teens */
  --thai:       #FF8A3D;   /* Striking */
  --womens:     #FF5FA8;   /* Women's */
  --specialty:  #E6EEFB;   /* Specialty — this value is for dark grounds only;
                                light grounds get their own in components.css */

  /* --- Header. One source of truth. The hero, every page header, the mobile
         panel and scroll anchoring all offset by these, so the nav can change
         height without three other files having to be told about it. --- */
  --nav-h:      64px;    /* the floating bar itself */
  --nav-inset:  0.9rem;  /* how far it floats off the top and sides */
  --nav-total:  calc(var(--nav-h) + var(--nav-inset) * 2);

  /* --- Type --- */
  --display: 'Archivo', 'Archivo Expanded', 'Helvetica Neue', Arial, sans-serif;
  --body:    'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* Fluid type scale. Ratio ~1.28, clamped so nothing gets silly on ultrawide. */
  --t-xs:   0.75rem;
  --t-sm:   0.8125rem;
  --t-base: clamp(1rem, 0.97rem + 0.14vw, 1.0625rem);
  --t-lg:   clamp(1.125rem, 1.06rem + 0.3vw, 1.3125rem);
  --t-xl:   clamp(1.375rem, 1.24rem + 0.6vw, 1.75rem);
  --t-2xl:  clamp(1.75rem, 1.5rem + 1.1vw, 2.5rem);
  --t-3xl:  clamp(2.25rem, 1.8rem + 2.1vw, 3.5rem);
  --t-4xl:  clamp(2.75rem, 1.9rem + 3.8vw, 5.25rem);
  --t-5xl:  clamp(3.25rem, 1.9rem + 5.6vw, 7rem);

  /* --- Space --- */
  --gap:      clamp(1rem, 0.7rem + 1.2vw, 1.75rem);
  --pad-x:    clamp(1.25rem, 0.8rem + 2.2vw, 2.5rem);
  /* Both of these used to bottom out at their clamp minimum on a phone — 72px and
     48px — because 3rem + 6vw at 390px is already above 4.5rem. So every section
     on mobile carried desktop padding. The minimums are now the mobile values and
     the vw term does the growing. */
  --section:  clamp(3.25rem, 1.6rem + 6vw, 8.75rem);
  --section-tight: clamp(2.5rem, 1.4rem + 4vw, 5.5rem);
  --shell:    1220px;
  --shell-narrow: 780px;

  /* --- Form --- */
  --r-sm: 4px;
  --r:    10px;
  --r-lg: 18px;
  --r-xl: 26px;

  /* --- Depth. Navy-tinted, never neutral grey. --- */
  --lift-1: 0 1px 2px rgba(0, 11, 31, 0.06), 0 4px 14px rgba(0, 11, 31, 0.05);
  --lift-2: 0 2px 4px rgba(0, 11, 31, 0.07), 0 14px 36px rgba(0, 11, 31, 0.09);
  --lift-3: 0 4px 8px rgba(0, 11, 31, 0.09), 0 28px 64px rgba(0, 11, 31, 0.16);
  --lift-blue: 0 10px 30px rgba(0, 102, 255, 0.28);

  /* --- Motion --- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out-back: cubic-bezier(0.34, 1.4, 0.64, 1);
  --dur: 0.42s;
  --dur-fast: 0.2s;
}

/* Below the desktop breakpoint the bar loses the links and only carries the
   wordmark and the menu button, so it does not need the height. */
@media (max-width: 999px) {
  :root { --nav-h: 58px; --nav-inset: 0.65rem; }
}

/* --------------------------------------------------------------------------
   2. RESET
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1.5rem);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--slate-deep);
  font-family: var(--body);
  font-size: var(--t-base);
  line-height: 1.62;
  font-feature-settings: 'kern' 1, 'liga' 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

img, picture, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

button { background: none; border: 0; cursor: pointer; }

a { color: inherit; text-decoration: none; }

table { border-collapse: collapse; width: 100%; }

address { font-style: normal; }

/* Accessible focus, visible on both grounds. */
:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.on-dark :focus-visible,
.s-ink :focus-visible,
.s-ink-2 :focus-visible {
  outline-color: #6FA8FF;
}

::selection {
  background: var(--blue);
  color: #fff;
}

/* Skip link */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.85rem 1.25rem;
  background: var(--blue);
  color: #fff;
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

/* --------------------------------------------------------------------------
   3. TYPOGRAPHY
   -------------------------------------------------------------------------- */

/* Display face: wide, heavy, uppercase, tight. Echoes the 10P wordmark. */
.d1, .d2, .d3, .d4 {
  font-family: var(--display);
  font-weight: 800;
  font-stretch: 125%;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  line-height: 0.94;
  color: inherit;
  text-wrap: balance;
  padding-bottom: 0.06em;
}

.d1 { font-size: var(--t-5xl); line-height: 0.9; letter-spacing: -0.018em; }
.d2 { font-size: var(--t-4xl); line-height: 0.92; letter-spacing: -0.014em; }
.d3 { font-size: var(--t-3xl); line-height: 0.96; letter-spacing: -0.01em; }
.d4 { font-size: var(--t-2xl); line-height: 1.0; }

/* Mono eyebrow — the recurring structural label. Carries a real value
   (a level code, a day, a count), never decoration. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-family: var(--mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue);
}
.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}
/* #4D93FF measured 3.9:1 against the dark grounds — under AA for 12px text.
   This lift clears 7:1 everywhere it is used. */
.on-dark .eyebrow,
.s-ink .eyebrow, .s-ink-2 .eyebrow { color: #8CBCFF; }

.lede {
  font-size: var(--t-lg);
  line-height: 1.58;
  color: var(--slate);
  max-width: 62ch;
  text-wrap: pretty;
}
.on-dark .lede,
.s-ink .lede, .s-ink-2 .lede { color: var(--on-ink-mid); }

.prose p { max-width: 66ch; color: var(--slate); text-wrap: pretty; }
.prose p + p { margin-top: 1.05em; }
.on-dark .prose p,
.s-ink .prose p, .s-ink-2 .prose p { color: var(--on-ink-mid); }
.prose strong { color: var(--slate-deep); font-weight: 600; }
.on-dark .prose strong,
.s-ink .prose strong, .s-ink-2 .prose strong { color: #fff; }

.prose a:not([class]) {
  color: var(--blue);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--dur-fast) var(--ease);
}
.prose a:not([class]):hover { color: var(--ink); }
.on-dark .prose a:not([class]) { color: #6FA8FF; }
.on-dark .prose a:not([class]):hover { color: #fff; }

/* Numerals set in mono read as data, which is what stats are. */
.stat-num {
  font-family: var(--mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 1;
}

/* --------------------------------------------------------------------------
   4. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}
.shell-narrow { max-width: var(--shell-narrow); }

.section { padding-block: var(--section); position: relative; }
.section-tight { padding-block: var(--section-tight); }

/* Section grounds. Each carries its own text color contract so nested
   components never have to guess which ground they're on. */
.s-paper { background: var(--paper); color: var(--slate-deep); }
.s-mist  { background: var(--mist);  color: var(--slate-deep); }
.s-ink   { background: var(--ink);   color: var(--on-ink); }
.s-ink-2 { background: var(--ink-2); color: var(--on-ink); }

.s-ink h1, .s-ink h2, .s-ink h3, .s-ink h4,
.s-ink-2 h1, .s-ink-2 h2, .s-ink-2 h3, .s-ink-2 h4 { color: #fff; }

/* Asymmetric feature split — 7/5, alternating side. Keeps the eye
   zig-zagging down the page instead of scanning a centered stack. */
.split {
  display: grid;
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 7fr 5fr; }
  .split.is-flipped { grid-template-columns: 5fr 7fr; }
  .split.is-flipped > :first-child { order: 2; }
  .split.is-even { grid-template-columns: 1fr 1fr; }
}

.grid { display: grid; gap: var(--gap); }
@media (min-width: 640px)  { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 720px)  { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 640px)  { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1060px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }

.stack > * + * { margin-top: var(--flow, 1.25rem); }
.stack-sm { --flow: 0.65rem; }
.stack-lg { --flow: 2rem; }

.center { text-align: center; margin-inline: auto; }
.measure { max-width: 58ch; }

/* --------------------------------------------------------------------------
   5. SECTION TRANSITION DEVICES
   The terminator: dark sections are the planet's night side, light ones the
   day side. Every dark→light seam gets the same atmosphere glow; every
   light→dark seam gets the same horizon rule. Consistency makes it a system
   rather than an effect.
   -------------------------------------------------------------------------- */

.atmos { position: relative; isolation: isolate; overflow: hidden; }
.atmos::before {
  content: '';
  position: absolute;
  inset-inline: -10%;
  top: 0;
  height: clamp(140px, 22vw, 300px);
  background: radial-gradient(
    ellipse 70% 100% at 50% 0%,
    var(--blue-24) 0%,
    var(--blue-08) 45%,
    transparent 78%
  );
  pointer-events: none;
  z-index: 0;
}
.atmos > * { position: relative; z-index: 1; }

.atmos-b { position: relative; isolation: isolate; overflow: hidden; }
.atmos-b::after {
  content: '';
  position: absolute;
  inset-inline: -10%;
  bottom: 0;
  height: clamp(140px, 22vw, 300px);
  background: radial-gradient(
    ellipse 70% 100% at 50% 100%,
    var(--blue-24) 0%,
    var(--blue-08) 45%,
    transparent 78%
  );
  pointer-events: none;
  z-index: 0;
}
.atmos-b > * { position: relative; z-index: 1; }

/* Horizon: the light→dark seam. A hairline with a soft bloom, the way a
   planet's limb reads against space. */
.horizon { position: relative; }
.horizon::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(1100px, 88%);
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--blue-40) 22%, var(--blue) 50%, var(--blue-40) 78%, transparent);
  opacity: 0.7;
}

/* --------------------------------------------------------------------------
   SECTION LINES
   Fine flowing contour lines across the whole of every section — families of
   hairline curves that taper as they cross, so they converge rather than
   repeat. They sit over a blue field rather than flat navy, which is what
   makes lines this faint readable at all, and they stay faint enough that
   body copy over them never loses contrast.

   Delivered as background layers on the section itself, not a pseudo element:
   .atmos and .horizon already own ::before. Every background property stays
   together on these compound selectors, because split across specificities a
   plain `background:` shorthand elsewhere resets background-size and the
   sizeless SVG then scales to fill the whole section.
   -------------------------------------------------------------------------- */

.s-ink.waves,
.s-ink-2.waves,
.s-paper.waves,
.s-mist.waves {
  background-repeat: no-repeat, no-repeat;
  background-position: 50% 50%, 50% 50%;
  background-size: cover, cover;
}

:root {
  --lines-dark:  url("../Images/field-dark.svg");
}

.s-ink.waves,
.s-ink-2.waves { background-image: var(--lines-dark), radial-gradient(ellipse 120% 90% at 62% 45%, #113A7E 0%, #0A2454 38%, #04122B 72%, #000B1F 100%); }

/* The line field is deliberately NOT used on the light grounds. On navy it reads
   as depth behind the content; on white it competes with dark body copy, and
   running it on every section turned a signature into wallpaper. Light sections
   keep the soft gradient only, so the field stays an accent. */
.s-paper.waves,
.s-mist.waves { background-image: radial-gradient(ellipse 120% 90% at 62% 45%, #EAF2FE 0%, transparent 72%); }

/* --------------------------------------------------------------------------
   6. UTILITIES
   -------------------------------------------------------------------------- */

.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.no-wrap { white-space: nowrap; }
.mono { font-family: var(--mono); }

/* --------------------------------------------------------------------------
   7. MOTION — opt-in reveals, and a hard off switch
   -------------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 0.7s var(--ease),
    transform 0.7s var(--ease);
  transition-delay: var(--reveal-delay, 0s);
  will-change: opacity, transform;
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* No-JS safety: never leave content hidden if the observer never runs. */
.no-js [data-reveal] { opacity: 1; transform: none; }
