/* ==========================================================================
   English with Stefan — site.css
   Built from Final Implementation Brief 1.1.
   One stylesheet. Design tokens are the first block below (Brief §8.1, J02).
   No inline style attributes are used anywhere in the markup: the CSP sets
   style-src 'self' with no 'unsafe-inline' (Brief §11, acceptance A08).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. DESIGN TOKENS  (Brief §8.1, §8.5, §8.6)
   -------------------------------------------------------------------------- */
:root {
  /* Colour */
  --navy:        #17243B;
  --blue:        #315A7A;
  --coral:       #D85F3F;
  --coral-deep:  #C15538;
  --taupe:       #AAA69A;
  --cloud:       #F4F6F5;
  --sand:        #EEE9E1;
  --white:       #FFFFFF;
  --ink:         #293646;

  /* Type families */
  --font-head: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-body: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;

  /* Fluid type scale */
  --fs-h1:      clamp(2rem, 1.35rem + 3vw, 3.25rem);
  --fs-h2:      clamp(1.5rem, 1.2rem + 1.6vw, 2.125rem);
  --fs-h3:      clamp(1.125rem, 1.05rem + 0.5vw, 1.375rem);
  --fs-body:    1rem;
  --fs-small:   0.875rem;
  --fs-eyebrow: 0.8125rem;

  /* Spacing scale */
  --s1:  4px;  --s2:  8px;  --s3: 12px;  --s4: 16px;  --s5: 24px;
  --s6: 32px;  --s7: 48px;  --s8: 64px;  --s9: 96px;  --s10: 128px;

  /* Layout */
  --measure:   62ch;
  --container: 1120px;
  --gutter:    20px;
  --header-h:  72px;

  /* Radii */
  --r-btn:   6px;
  --r-panel: 10px;
}

@media (min-width: 720px) {
  :root {
    --fs-body: 1.0625rem;
    --gutter:  24px;
  }
}

/* --------------------------------------------------------------------------
   2. SELF-HOSTED FONTS  (Brief §10 A9–A11, acceptance G06, G07, G08)
   Source Serif 4 and Source Sans 3, SIL Open Font Licence — see OFL.txt in
   this folder. Never loaded from Google: fonts.googleapis.com and
   fonts.gstatic.com are unreliable or blocked from mainland China, and a
   render-blocking request to an unreachable host is a blank page for the
   exact audience this site exists for.

   Four files, which is the cap. Three carry the `latin` subset; the fourth
   carries `latin-ext` for the body weight only.

   On subsets: the brief requires latin-ext because "Gnjatić contains ć". The
   approved copy spells it Gnjatic, without the diacritic, and every non-ASCII
   character the page actually uses — © · — ' " " — sits inside the latin
   subset. The ext file is therefore insurance, not a requirement: the
   unicode-range below means a browser downloads it only if such a character
   ever appears. Today that costs zero bytes. Acceptance item G10 fails the
   build if copy is ever added that these files cannot render.
   -------------------------------------------------------------------------- */

/* Google's standard `latin` subset range. */
@font-face {
  font-family: "Source Serif 4";
  src: url("/assets/fonts/source-serif-4-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext, body weight only. Downloaded solely if a character in this range
   appears — e.g. if "Gnjatic" is ever written "Gnjatić". */
@font-face {
  font-family: "Source Sans 3";
  src: url("/assets/fonts/source-sans-3-ext-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
                 U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                 U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------------------
   3. RESET AND BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  color-scheme: light;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  overflow-x: hidden;
}

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

h1, h2, h3 {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--navy);
  margin: 0 0 var(--s4);
}
h1 { font-size: var(--fs-h1); line-height: 1.12; }
h2 { font-size: var(--fs-h2); line-height: 1.18; }
h3 { font-size: var(--fs-h3); line-height: 1.3;  }

p { margin: 0 0 var(--s4); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: var(--blue); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--coral-deep); }

ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

hr { border: 0; margin: 0; }

/* --------------------------------------------------------------------------
   4. FOCUS INDICATION  (Brief §8.9, acceptance E03, E04, C11)
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}
.btn--primary:focus-visible { outline-color: var(--white); }
.contact :focus-visible,
.site-footer :focus-visible { outline-color: var(--coral); }

/* Focus moved programmatically after an in-page CTA (Brief §4).
   Deliberately visible — a reader who has been relocated must see where
   they landed. Applied by class, never by :focus. */
.is-focus-target {
  outline: 2px solid var(--coral);
  outline-offset: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy);
  color: var(--white);
  padding: var(--s3) var(--s4);
  text-decoration: none;
  border-radius: 0 0 var(--r-btn) 0;
}
.skip-link:focus {
  left: 0;
  color: var(--white);
}

/* --------------------------------------------------------------------------
   5. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: clamp(56px, 8vw, 112px); }
.section__title { margin-bottom: var(--s5); }
.subsection__title { margin-top: var(--s8); }
.section__cta { margin-top: var(--s7); }

/* Section backgrounds (Brief §8.3) */
.section--hero         { background: var(--sand);  }
.section--trust        { background: var(--white); }
.section--lessons      { background: var(--cloud); }
.section--about        { background: var(--white); }
.section--testimonials { background: var(--sand);  }
.section--quals        { background: var(--white); }
.section--trial        { background: var(--white); }

/* Every element carrying an anchor id (Brief §3) */
#trust, #lessons, #about, #approach, #qualifications, #free-trial, #privacy {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

/* Thin coral rules — the signature treatment. At most four on the page. */
.rule {
  height: 1px;
  background: var(--coral);
  margin-block: var(--s6);
}
.rule--short { width: 48px; margin-block: var(--s6) var(--s4); }

.eyebrow {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--blue);
  font-weight: 600;
}
.lead  { font-size: 1.0625em; }
.note  { font-size: var(--fs-small); color: var(--ink); }
.aside { font-size: var(--fs-small); }

/* --------------------------------------------------------------------------
   6. BUTTONS  (Brief §9)
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 44px;
  padding: 14px 24px;
  border: 0;
  border-radius: var(--r-btn);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms ease-out, border-color 120ms ease-out;
}
.btn--primary { background: var(--coral-deep); color: var(--white); }
.btn--primary:hover { background: #AB4B31; color: var(--white); }

.btn--secondary {
  background: transparent;
  border: 1.5px solid var(--blue);
  color: var(--blue);
}
.btn--secondary:hover { border-color: var(--coral-deep); color: var(--coral-deep); }

.btn--compact { min-height: 44px; padding: 10px 18px; }

/* --------------------------------------------------------------------------
   7. HEADER AND NAVIGATION  (Brief §3)
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--sand);
  transition: padding 160ms ease-out, background-color 160ms ease-out;
}
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding-block: 20px;
  transition: padding 160ms ease-out;
}
.site-header.is-compact {
  background: var(--white);
  border-bottom: 1px solid var(--taupe);
}
.site-header.is-compact .site-header__inner { padding-block: 10px; }
.site-header.is-compact .wordmark { font-size: 1.0125rem; }

.wordmark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.125rem;
  color: var(--navy);
  text-decoration: none;
  line-height: 1.2;
  margin-right: auto;
  transition: font-size 160ms ease-out;
}
.wordmark:hover { color: var(--navy); }

.site-nav { display: none; }
.site-nav__list { display: flex; gap: var(--s5); }
.site-nav__list a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Both dimensions, not just height. "About" is only 36px of text, so a
     height-only rule left it under the 44px target. */
  min-height: 44px;
  min-width: 44px;
  color: var(--navy);
  text-decoration: none;
  font-size: var(--fs-small);
  font-weight: 600;
}
.site-nav__list a:hover { color: var(--coral-deep); text-decoration: underline; }

/* Desktop navigation only (Brief §3). Below 720px the header is the wordmark
   plus the Free-trial button — no hamburger, no drawer, no focus trap. */
@media (min-width: 1080px) {
  .site-nav { display: block; }
}

/* --------------------------------------------------------------------------
   8. HERO  (Brief §2, §9)
   DOM order is the approved mobile order. The desktop two-column layout is
   a CSS Grid rearrangement of non-focusable content only: the sole focusable
   element here is the CTA, so focus order never diverges from visual order.
   -------------------------------------------------------------------------- */
.hero { display: grid; gap: var(--s5); }
.hero__eyebrow  { grid-area: eyebrow;  margin-bottom: 0; }
.hero__headline { grid-area: headline; margin-bottom: 0; }
.hero__portrait { grid-area: portrait; }
.hero__cta      { grid-area: cta;      margin-bottom: 0; max-width: none; }
.hero__support  { grid-area: support;  margin-bottom: 0; }
.hero__note     { grid-area: note;     margin-bottom: 0; }

.hero {
  grid-template-areas:
    "eyebrow"
    "headline"
    "portrait"
    "cta"
    "support"
    "note";
}

/* The portrait is a cutout composited onto Pale sand, so it sits directly on
   the section with no panel, no padding and no rounded corners. If the hero
   section background ever changes, the image must be regenerated - the colour
   is baked into the JPEG. See tools/prepare-images.ps1. */
.hero__portrait picture { display: block; }
.hero__portrait img {
  width: 100%;
  min-width: 260px;
  /* Capped on mobile so the CTA below it stays above the fold on a 375x812
     screen (acceptance F10). Cropping from the top keeps the head large;
     the trimmed edge is beige against beige, so the cut is invisible. */
  max-height: 42vh;
  object-fit: cover;
  object-position: center top;
}

@media (min-width: 720px) {
  .hero__portrait img { max-height: 52vh; }
}

@media (min-width: 1080px) {
  .hero {
    /* Wider column than the old panelled version. With the 24px panel padding
       gone as well, this renders the portrait about 20% larger: measured 482px
       against 402px before, at a 1440px viewport. */
    grid-template-columns: 1fr minmax(340px, 45%);
    grid-template-areas:
      "eyebrow  portrait"
      "headline portrait"
      "support  portrait"
      "cta      portrait"
      "note     portrait";
    column-gap: var(--s8);
    align-items: start;
  }
  .hero__portrait { align-self: start; }
  .hero__portrait img { max-height: none; object-fit: fill; }
}

/* --------------------------------------------------------------------------
   9. TRUST STRIP, PROBLEM, OUTCOMES
   -------------------------------------------------------------------------- */
.trust { display: grid; gap: var(--s6); }
.trust dt {
  font-weight: 600;
  color: var(--navy);
  margin-bottom: var(--s2);
}
.trust dd { max-width: var(--measure); }

@media (min-width: 720px) {
  .trust { grid-template-columns: repeat(2, 1fr); gap: var(--s6) var(--s7); }
}
@media (min-width: 1080px) {
  .trust { grid-template-columns: repeat(4, 1fr); }
}

.problem { margin-top: var(--s9); }

.outcomes {
  display: grid;
  gap: var(--s4);
  margin-top: var(--s7);
}
.outcomes li {
  position: relative;
  padding-left: var(--s5);
  font-weight: 600;
  color: var(--navy);
}
.outcomes li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  background: var(--coral);
}
@media (min-width: 720px) {
  .outcomes { grid-template-columns: repeat(3, 1fr); gap: var(--s6); }
}

/* --------------------------------------------------------------------------
   10. LESSON GOALS, FIT NOTE, STEPS
   -------------------------------------------------------------------------- */
.goal { margin-top: var(--s7); }
.goal h3 { margin-bottom: var(--s3); }

.fit {
  margin-top: var(--s8);
  padding: 20px;
  background: var(--sand);
  border-radius: var(--r-btn);
  font-size: 0.9375rem;
}
.fit__lead { margin-bottom: var(--s2); }
.fit__lead strong { color: var(--navy); }

.steps { display: grid; gap: var(--s6); margin-top: var(--s5); counter-reset: step; }
.steps__item { counter-increment: step; }
.steps__title { margin-bottom: var(--s2); }
.steps__title::before {
  content: counter(step) " · ";
  font-family: var(--font-head);
  color: var(--coral-deep);
  font-weight: 600;
}
.steps__title strong { color: var(--navy); }

@media (min-width: 720px) {
  .steps { grid-template-columns: repeat(2, 1fr); gap: var(--s7); }
}

/* --------------------------------------------------------------------------
   11. ABOUT AND APPROACH
   -------------------------------------------------------------------------- */
.about { display: grid; gap: var(--s7); }
.about__text     { grid-area: text; }
.about__portrait { grid-area: portrait; }
.about__approach { grid-area: approach; }

.about {
  grid-template-areas:
    "text"
    "portrait"
    "approach";
}
.about__portrait img { width: 100%; border-radius: var(--r-panel); }
.about__approach h3 { margin-top: var(--s7); }
.about__approach h3:first-of-type { margin-top: 0; }

@media (min-width: 1080px) {
  .about {
    grid-template-columns: 1fr minmax(260px, 34%);
    grid-template-areas:
      "text     portrait"
      "approach portrait";
    column-gap: var(--s8);
    align-items: start;
  }
  .about__portrait { align-self: start; }
}

/* --------------------------------------------------------------------------
   12. TESTIMONIALS
   -------------------------------------------------------------------------- */
.quote { margin: 0; }
.quote p { font-size: 1rem; }
.quote cite {
  display: block;
  margin-top: var(--s3);
  font-style: normal;
  font-size: var(--fs-small);
  color: var(--blue);
}

.quote--featured {
  background: var(--white);
  border-radius: var(--r-panel);
  padding: var(--s6);
}
.quote--featured p { font-size: 1.125rem; }

.quotes { display: grid; gap: var(--s6); margin-top: var(--s7); }
.quotes .quote {
  border-left: 1px solid var(--taupe);
  padding-left: 20px;
}
@media (min-width: 1080px) {
  .quotes { grid-template-columns: repeat(3, 1fr); gap: var(--s7); }
}

/* --------------------------------------------------------------------------
   13. QUALIFICATIONS
   -------------------------------------------------------------------------- */
.quals { display: grid; gap: var(--s7); }
.qual__title {
  font-family: var(--font-head);
  font-size: var(--fs-h3);
  font-weight: 600;
  color: var(--navy);
  margin-bottom: var(--s1);
}
.qual__detail  { margin-bottom: var(--s1); }
.qual__program { font-size: var(--fs-small); color: var(--blue); margin-bottom: 0; }

@media (min-width: 720px) {
  .quals { grid-template-columns: repeat(2, 1fr); }
}

/* --------------------------------------------------------------------------
   14. WECHAT CONTACT BLOCK  (Brief §6)
   Mobile renders in DOM order: title, fit, ID, copy, live region, hint,
   QR block, email, first message.
   Desktop moves the QR block into the visually primary column. The only
   focusable elements — the Copy button and the email link — stay in DOM
   order in the second column, so focus order and visual order do not
   diverge (WCAG 2.4.3). No flex `order` is used on focusable children.
   -------------------------------------------------------------------------- */
.contact {
  margin-top: var(--s8);
  background: var(--navy);
  color: var(--white);
  border-radius: var(--r-panel);
  padding: var(--s6);
  display: grid;
  gap: var(--s5);
}
.contact__title  { grid-area: title;  color: var(--white); margin-bottom: 0; }
.contact__fit    { grid-area: fit;    margin-bottom: 0; font-size: var(--fs-small); }
.contact__id     { grid-area: id;     }
.contact__copyslot { grid-area: copy; }
.contact__live   { grid-area: live;   margin-bottom: 0; min-height: 1.5em; font-size: var(--fs-small); }
.contact__hint   { grid-area: hint;   margin-bottom: 0; font-size: var(--fs-small); }
.contact__qrblock { grid-area: qr;    }
.contact__email  { grid-area: email;  }
.contact__first  { grid-area: first;  }

.contact {
  grid-template-areas:
    "title"
    "fit"
    "id"
    "copy"
    "live"
    "hint"
    "qr"
    "email"
    "first";
}

.contact__idlabel {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--taupe);
  margin-bottom: var(--s1);
}
.contact__idvalue {
  font-family: var(--font-head);
  font-size: clamp(1.5rem, 1.2rem + 1.6vw, 2rem);
  color: var(--white);
  margin-bottom: 0;
  user-select: all;
  word-break: break-all;
}
.contact__live { color: var(--taupe); }
.contact__live:not(:empty) { color: var(--white); }

/* The QR is a real <img>, lossless PNG, on its own white panel so the quiet
   zone survives against the navy ground. Fixed size, never fluid. */
.contact__qr {
  background: var(--white);
  border-radius: var(--r-btn);
  padding: 12px;
  width: max-content;
  max-width: 100%;
}
.contact__qr img { width: 240px; height: 240px; }

.contact__longpress,
.contact__scan { font-size: var(--fs-small); color: var(--taupe); margin-top: var(--s3); }
.contact__scan { margin-bottom: 0; }

.contact__emaillabel {
  font-size: var(--fs-eyebrow);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--taupe);
  margin-bottom: var(--s1);
}
.contact__emailvalue { margin-bottom: 0; }
.contact__emailvalue a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--white);
}
.contact__emailvalue a:hover { color: var(--coral); }

.contact__firstlead { font-size: var(--fs-small); color: var(--taupe); margin-bottom: var(--s2); }
.contact__firstbody {
  border-left: 1px solid var(--taupe);
  padding-left: var(--s4);
  font-size: 0.9375rem;
  margin-bottom: 0;
  user-select: all;
}

.contact .btn--secondary { border-color: var(--white); color: var(--white); }
.contact .btn--secondary:hover { border-color: var(--coral); color: var(--coral); }

@media (min-width: 720px) {
  .contact {
    grid-template-columns: minmax(264px, 45%) 1fr;
    grid-template-areas:
      "qr title"
      "qr fit"
      "qr id"
      "qr copy"
      "qr live"
      "qr hint"
      "qr email"
      "qr first";
    column-gap: var(--s7);
    padding: var(--s7);
    align-items: start;
  }
  .contact__qrblock { align-self: start; }
  .contact__qr img { width: 280px; height: 280px; }
  /* Long-press extraction is a touch behaviour — the instruction is noise on
     a desktop (Brief §6, acceptance D03). */
  .contact__longpress { display: none; }
}

/* --------------------------------------------------------------------------
   15. PRIVACY AND FOOTER
   -------------------------------------------------------------------------- */
.privacy { margin-top: var(--s8); }
.privacy p { font-size: var(--fs-small); }
.privacy__title { font-size: var(--fs-h3); }
.privacy__meta { color: var(--blue); }

.site-footer {
  background: var(--white);
  border-top: 1px solid var(--taupe);
  padding-block: var(--s7);
}
.site-footer__inner { display: grid; gap: var(--s5); }
.site-footer__brand {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--navy);
  margin-bottom: var(--s1);
}
.site-footer__tagline { font-size: var(--fs-small); margin-bottom: 0; }
.site-footer__links { display: grid; gap: var(--s2); font-size: var(--fs-small); }
.site-footer__links a {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 44px;
  min-width: 44px;
}
.site-footer__copyright { color: var(--blue); display: flex; align-items: center; min-height: 44px; }

@media (min-width: 720px) {
  .site-footer__inner {
    grid-template-columns: 1fr auto;
    align-items: end;
  }
  .site-footer__links { justify-items: end; }
}

/* --------------------------------------------------------------------------
   16. MOTION  (Brief §8.8)
   HARD RULE: the base stylesheet never sets opacity:0 on content. The start
   state lives behind the .js-anim class, which JavaScript adds only when
   prefers-reduced-motion is not "reduce". A visitor without JavaScript, or
   with IntersectionObserver unsupported, sees everything immediately.
   -------------------------------------------------------------------------- */
.js-anim .reveal {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 240ms ease-out, transform 240ms ease-out;
}
.js-anim .reveal.is-visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js-anim .reveal { opacity: 1; transform: none; }
}
