// CoursesPage.jsx

/* Course-id mapping for the basket on the Pricing page.
   ALL_COURSES uses numeric ids; SINGLE_COURSES in PricingPage uses string ids.
   This map lets us hand off a "user wants to buy this course" intent. */
const COURSE_BASKET_KEY = {
  1: 'fire',
  2: 'allergy',
  3: 'food1',
  4: 'food2',
  5: 'firstaid',
  6: 'dys-school',
  7: 'dys-uni',
  8: 'dys-work',
};

/* Per-course price — replaces the previous brittle `course.id === 4 ? £29 : £19`
   inline branch. Add the course id to override; defaults to £19. */
const COURSE_PRICE = {
  4: 26,    // Food Safety L2 (supervisory) — pre-order price (post-launch £38)
};

/* Per-course pass mark — mirrors prototype-data.jsx (c_fire 80, c_allergy 80,
   c_food1 75, c_food2 80, c_firstaid 75); dyslexia courses default to 80. */
const COURSE_PASS_MARK = {
  1: 80,    // Fire Safety Awareness
  2: 80,    // Food Allergy Awareness
  3: 75,    // Food Safety & Hygiene L1
  4: 80,    // Food Safety & Hygiene L2
  5: 75,    // First Aid Awareness
  6: 80,    // Navigating School with Dyslexia
  7: 80,    // Navigating University with Dyslexia
  8: 80,    // Navigating the Workplace with Dyslexia
};

/* Per-course detail used in the side drawer — lesson outline + a sample
   assessment question to make the drawer feel like a real preview. */
const COURSE_OUTLINE = {
  1: {
    lessons: [
      'Why fire safety matters at work',
      'Common causes of workplace fires',
      'Evacuation routes and assembly points',
      'Fire extinguisher types and when to use which',
      'Your legal duties and where to learn more',
    ],
    sample: {
      q: 'You spot a small fire in a back-of-house bin. The nearest extinguisher is a CO₂. What do you do first?',
      a: ['Use the CO₂ on the fire and shout for help.', 'Raise the alarm, then tackle only if safe.', 'Open the back door to clear the smoke.'],
      correct: 1,
    },
  },
  2: {
    lessons: [
      'The 14 major allergens — recognise them on sight',
      'Cross-contamination in a busy kitchen',
      'Natasha\'s Law and PPDS labelling',
      'Handling customer allergen enquiries',
      'When to escalate to the chef or manager',
      'Recap, scenarios, and assessment',
    ],
    sample: {
      q: 'A guest asks if the bread contains sesame. The label doesn\'t say. What\'s the right call?',
      a: ['Tell them you think it\'s fine and serve it.', 'Check with the chef before serving or offer an alternative.', 'Ask another guest at the table.'],
      correct: 1,
    },
  },
  3: {
    lessons: [
      'Personal hygiene on shift',
      'Hand washing and PPE basics',
      'Temperature controls — hot, cold, danger zone',
      'Safe storage and stock rotation',
      'Avoiding cross-contamination',
      'Cleaning, sanitation and waste',
      'Recap and assessment',
    ],
    sample: {
      q: 'You take a chicken thigh out of the fridge to prep. The probe reads 7°C. What should happen next?',
      a: ['Use it straight away, that\'s fine.', 'Return to the fridge — the danger zone starts at 8°C.', 'Note the temperature in the daily log and continue safely.'],
      correct: 2,
    },
  },
  4: {
    lessons: [
      'HACCP — the seven principles in plain English',
      'Hazard analysis for your kitchen',
      'Critical control points and limits',
      'Managing allergens at supervisory level',
      'Documentation that an inspector accepts',
      'Supplier and delivery checks',
      'Pest control, cleaning schedules',
      'Training and supervisory responsibility',
      'Recap and assessment',
    ],
    sample: {
      q: 'Which of these is a critical control point in a typical service?',
      a: ['Garnishing a finished dish.', 'Cooking chicken to 75°C core.', 'Wiping down a serving counter.'],
      correct: 1,
    },
  },
  5: {
    lessons: [
      'Recognising when first aid is needed',
      'CPR — the basic steps with confidence',
      'Choking, burns and minor bleeding',
      'Reporting and recording incidents',
      'When to call 999 — and what to say',
    ],
    sample: {
      q: 'A colleague has burned their hand on a pan. What do you do first?',
      a: ['Wrap it in a clean tea-towel and carry on.', 'Run it under cool running water for at least 10 minutes.', 'Apply butter to soothe it.'],
      correct: 1,
    },
  },
  // ── Dyslexia programme ──
  6: {
    lessons: [
      'What dyslexia is — and what it isn\'t',
      'Reading strategies that work — phonics, chunking, audio',
      'Spelling and writing — scaffolding, not pretending',
      'Using dictation and read-aloud at school',
      'Asking for adjustments without feeling small',
      'Preparing for exams and revision',
    ],
    sample: {
      q: 'You\'ve been given a long worksheet to read silently in class. Nothing on screen, only paper. What\'s a reasonable first ask?',
      a: ['Soldier through — getting help feels embarrassing.', 'Ask for a digital or audio version so you can read it your way.', 'Skip ahead to the questions and guess.'],
      correct: 1,
    },
  },
  7: {
    lessons: [
      'Picking the right course and disclosing on UCAS',
      'Applying for the Disabled Students\' Allowance (DSA)',
      'Reading academic texts — skim, scaffold, summarise',
      'Lectures, notes and recording tools',
      'Essay structure, writing and editing tech',
      'Deadlines, overwhelm and asking for extensions',
    ],
    sample: {
      q: 'You have a 3,000-word essay due in two weeks and 12 sources to read. What\'s a sensible first move?',
      a: ['Read every source cover-to-cover before writing.', 'Use text-to-speech to skim each source first and pick the 4–5 most relevant.', 'Email the tutor that you can\'t do it.'],
      correct: 1,
    },
  },
  8: {
    lessons: [
      'Dyslexia at work in plain English',
      'Disclosure — when, who, and how',
      'Reasonable adjustments under the Equality Act',
      'Email, report and meeting tools that quietly help',
      'Pair-working and asking for proof-reads',
      'Building a personal toolkit',
      'For managers: supporting a dyslexic colleague',
    ],
    sample: {
      q: 'A manager asks for a written report by end of day. You write much slower than you talk. What\'s a reasonable adjustment to suggest?',
      a: ['Stay late and push through alone.', 'Dictate a draft and have it proof-read by a colleague before sending.', 'Send a voicemail and hope for the best.'],
      correct: 1,
    },
  },
};

const ALL_COURSES = [
  {
    id: 1,
    programme: 'food',
    title: 'Fire Safety Awareness',
    tag: 'Essential',
    duration: '~20 min',
    lessons: 5,
    level: 'All staff',
    desc: 'Covers fire prevention, the causes of workplace fires, evacuation procedures, fire extinguisher types, and legal responsibilities under the Regulatory Reform (Fire Safety) Order 2005.',
    outcomes: [
      'Understand common causes of workplace fires',
      'Know evacuation routes and assembly points',
      'Identify fire extinguisher types and their uses',
      'Understand legal duties for employers and staff',
    ],
    legislation: 'Regulatory Reform (Fire Safety) Order 2005',
  },
  {
    id: 2,
    programme: 'food',
    title: 'Food Allergy Awareness',
    tag: "Natasha's Law",
    duration: '~25 min',
    lessons: 6,
    level: 'All food staff',
    desc: 'The 14 major allergens, cross-contamination risks, labelling obligations under Natasha\'s Law, and how to handle customer allergen enquiries correctly and confidently.',
    outcomes: [
      'Name the 14 major allergens under UK law',
      'Understand cross-contamination and how to prevent it',
      'Know labelling obligations under Natasha\'s Law (PPDS)',
      'Handle customer allergen queries safely',
    ],
    legislation: "Natasha's Law (PPDS) · Food Information Regulations 2014",
  },
  {
    id: 3,
    programme: 'food',
    title: 'Food Safety & Hygiene Level 1',
    tag: 'Foundation',
    duration: '~30 min',
    lessons: 7,
    level: 'Kitchen & food handlers',
    desc: 'Personal hygiene, temperature control, safe food storage, contamination prevention and basic HACCP awareness. The foundation for any food-handling role.',
    outcomes: [
      'Maintain personal hygiene standards on shift',
      'Apply safe temperature and storage controls',
      'Prevent contamination in a food environment',
      'Understand the basics of HACCP',
    ],
    legislation: 'Food Safety Act 1990 · Food Hygiene Regulations 2006',
  },
  {
    id: 4,
    programme: 'food',
    title: 'Food Safety & Hygiene Level 2',
    tag: 'Supervision',
    duration: '~45 min',
    lessons: 9,
    level: 'Supervisors & chefs',
    desc: 'A deeper dive into food safety management systems, hazard analysis, supervisory responsibilities, and managing a food-safe kitchen under UK and EU-retained legislation.',
    outcomes: [
      'Implement a food safety management system',
      'Conduct hazard analysis for your kitchen',
      'Manage allergen controls and documentation',
      'Understand supervisory legal responsibilities',
    ],
    legislation: 'Food Safety Act 1990 · Regulation (EC) No 852/2004',
  },
  {
    id: 5,
    programme: 'food',
    title: 'First Aid Awareness',
    tag: 'Safety',
    duration: '~20 min',
    lessons: 5,
    level: 'All staff',
    desc: 'Basic first aid response including CPR awareness, choking, burns, bleeding, and incident reporting. Not a replacement for First Aid at Work certification.',
    outcomes: [
      'Recognise when someone needs first aid',
      'Perform basic CPR steps with confidence',
      'Respond to choking, burns and minor bleeding',
      'Know how to report and record incidents',
    ],
    legislation: 'Health & Safety (First-Aid) Regulations 1981',
  },

  // ── Dyslexia programme — for dyslexic learners and the people who teach,
  // mentor, or manage them. Written from the inside: practical, kind, no jargon.
  {
    id: 6,
    programme: 'dyslexia',
    title: 'Navigating School with Dyslexia',
    tag: 'Students',
    duration: '~35 min',
    lessons: 6,
    level: 'Students, parents, teachers',
    desc: 'A practical course for dyslexic pupils, their families, and the teachers supporting them. Strategies for reading, writing, and exams — plus how to ask for the right adjustments without feeling small.',
    outcomes: [
      'Understand what dyslexia is — and what it isn\'t',
      'Build reading and spelling strategies that actually work',
      'Use audio, dictation, and assistive tech with confidence',
      'Know how to ask for adjustments in lessons and exams',
    ],
    legislation: 'Equality Act 2010 · SEND Code of Practice 2015',
  },
  {
    id: 7,
    programme: 'dyslexia',
    title: 'Navigating University with Dyslexia',
    tag: 'Higher Ed',
    duration: '~40 min',
    lessons: 6,
    level: 'University & college students',
    desc: 'Move from school to higher education with a clear plan. Apply for the Disabled Students\' Allowance, read academic texts strategically, and stay on top of essays and deadlines without burning out.',
    outcomes: [
      'Apply for the Disabled Students\' Allowance (DSA)',
      'Read and summarise academic texts strategically',
      'Use lecture recording, dictation, and editing tools',
      'Manage essays, deadlines, and overwhelm',
    ],
    legislation: 'Equality Act 2010 · DSA guidance (Department for Education)',
  },
  {
    id: 8,
    programme: 'dyslexia',
    title: 'Navigating the Workplace with Dyslexia',
    tag: 'Workplace',
    duration: '~45 min',
    lessons: 7,
    level: 'Working adults & managers',
    desc: 'Thrive at work as a dyslexic adult. When and how to disclose, what reasonable adjustments to ask for, and the tools that quietly handle the daily reading and writing load. Includes a track for managers supporting a dyslexic colleague.',
    outcomes: [
      'Decide when and how to disclose at work',
      'Know your rights to reasonable adjustments',
      'Build a personal toolkit for emails, reports and meetings',
      'Support a dyslexic colleague as a manager',
    ],
    legislation: 'Equality Act 2010 · ACAS reasonable adjustments guidance',
  },
];

// Per-programme filter pills. Food has many categories; Dyslexia is a small
// curated set so no filter is needed yet.
const FOOD_FILTERS = ['All', 'Essential', 'Foundation', 'Supervision', "Natasha's Law", 'Safety'];

// Short, complete descriptions used in the row view (no ellipsis truncation).
const ROW_BLURB = {
  1: 'Fire prevention, evacuation, extinguisher types, and legal duties for every member of staff.',
  2: 'The 14 allergens, cross-contamination, Natasha\'s Law labelling, and how to handle customer enquiries.',
  3: 'Personal hygiene, temperature control, safe storage, and the basics of HACCP for food handlers.',
  4: 'Hazard analysis, food safety management, allergen control, and supervisory legal responsibilities.',
  5: 'CPR awareness, choking, burns and bleeding, plus how to record and report workplace incidents.',
  6: 'Reading strategies, spelling scaffolds, exam adjustments, and the tools that quietly carry the load at school.',
  7: 'DSA, academic reading, lecture recording, essay editing — the realistic toolkit for higher-ed life with dyslexia.',
  8: 'Disclosure, reasonable adjustments, daily-work tools, and how to manage a dyslexic colleague well.',
};

const CourseDetailPanel = ({ course, onClose, onNav }) => {
  // Escape closes the drawer
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [onClose]);

  // Move focus into the drawer when it opens so keyboard users land inside it
  const panelRef = React.useRef(null);
  React.useEffect(() => { panelRef.current && panelRef.current.focus(); }, []);

  const outline = COURSE_OUTLINE[course.id] || { lessons: [], sample: null };

  // "Add to basket" — store the pending course-id and quantity in localStorage,
  // then navigate to Pricing. PricingPage reads the pending basket on mount.
  const addToBasket = (alsoOpenCheckout) => {
    try {
      const key = COURSE_BASKET_KEY[course.id];
      if (key) {
        const raw = localStorage.getItem('tc:pending-basket');
        const prev = raw ? JSON.parse(raw) : {};
        prev[key] = (prev[key] || 0) + 1;
        if (alsoOpenCheckout) prev.__openCheckout = true;
        localStorage.setItem('tc:pending-basket', JSON.stringify(prev));
      }
    } catch (e) {}
    onClose();
    // Land directly on the basket section so the just-added licence is visible.
    if (onNav) onNav('pricing#individual-courses');
  };

  return (
    <div ref={panelRef} tabIndex={-1} role="dialog" aria-modal="true" aria-label={course.title} style={{
      position: 'fixed', top: 0, right: 0, bottom: 0, width: 'min(480px, 100vw)', zIndex: 300,
      background: C.parchment, borderLeft: `1px solid ${C.border}`,
      boxShadow: '-8px 0 40px rgba(26,25,23,0.12)',
      display: 'flex', flexDirection: 'column',
    }}>
      <div style={{ padding: '24px 28px', borderBottom: `1px solid ${C.border}`, display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
        <div style={{ minWidth: 0 }}>
          <div style={{ background: C.brassDim, borderRadius: 9999, padding: '4px 12px', display: 'inline-flex', marginBottom: 10, whiteSpace: 'nowrap' }}>
            <span style={{ fontFamily: F.sans, fontSize: 9, fontWeight: 600, letterSpacing: '1.5px', textTransform: 'uppercase', color: C.brass }}>{course.tag}</span>
          </div>
          <h2 style={{ fontFamily: F.display, fontStyle: 'italic', fontSize: 24, fontWeight: 400, color: C.ink, lineHeight: 1.25 }}>{course.title}</h2>
        </div>
        <button onClick={onClose} aria-label="Close" style={{ background: 'none', border: 'none', cursor: 'pointer', color: C.dust, fontSize: 20, padding: 0, flexShrink: 0, width: 32, height: 32, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>✕</button>
      </div>
      <div style={{ padding: '24px 28px', flex: 1, overflowY: 'auto' }}>
        {/* Meta */}
        <div style={{ display: 'flex', gap: 20, marginBottom: 22, flexWrap: 'wrap' }}>
          {[
            { label: 'Duration', val: course.duration },
            { label: 'Lessons', val: `${course.lessons} lessons` },
            { label: 'Level', val: course.level },
          ].map(({ label, val }) => (
            <div key={label}>
              <div style={{ fontFamily: F.sans, fontSize: 9, fontWeight: 600, letterSpacing: '1.5px', textTransform: 'uppercase', color: C.dust, marginBottom: 4 }}>{label}</div>
              <div style={{ fontFamily: F.body, fontSize: 13, fontWeight: 500, color: C.ink }}>{val}</div>
            </div>
          ))}
        </div>
        <HR style={{ marginBottom: 20 }} />
        <p style={{ fontFamily: F.body, fontSize: 14.5, color: C.ash, lineHeight: 1.70, marginBottom: 24 }}>{course.desc}</p>

        {/* Lesson outline */}
        {outline.lessons.length > 0 && (
          <div style={{ marginBottom: 24 }}>
            <Label color={C.brass} mb={12}>Lesson outline</Label>
            <ol style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {outline.lessons.map((l, i) => (
                <li key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '8px 12px', background: C.linen, borderRadius: 8, border: `1px solid ${C.borderSubtle}` }}>
                  <span style={{
                    flexShrink: 0, width: 22, height: 22, borderRadius: '50%',
                    background: C.parchment, border: `1px solid ${C.border}`,
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: F.mono, fontSize: 10.5, fontWeight: 600, color: C.brass,
                  }}>{i + 1}</span>
                  <span style={{ fontFamily: F.body, fontSize: 13.5, color: C.ink, lineHeight: 1.45, minWidth: 0 }}>{l}</span>
                </li>
              ))}
            </ol>
          </div>
        )}

        {/* Outcomes */}
        <div style={{ marginBottom: 24 }}>
          <Label color={C.brass} mb={12}>What you'll learn</Label>
          {course.outcomes.map(o => (
            <div key={o} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', marginBottom: 8 }}>
              <div style={{ width: 4, height: 4, borderRadius: '50%', background: C.river, marginTop: 7, flexShrink: 0 }} />
              <span style={{ fontFamily: F.body, fontSize: 14, color: C.ash, lineHeight: 1.55 }}>{o}</span>
            </div>
          ))}
        </div>

        {/* Sample assessment question */}
        {outline.sample && (
          <div style={{ background: C.brassDim, border: `1px solid rgba(107,46,46,0.25)`, borderRadius: 10, padding: '16px 18px', marginBottom: 24 }}>
            <Label color={C.brass} mb={10}>Sample assessment question</Label>
            <div style={{ fontFamily: F.body, fontSize: 13.5, color: C.ink, lineHeight: 1.55, marginBottom: 12, fontWeight: 500 }}>{outline.sample.q}</div>
            {outline.sample.a.map((opt, i) => (
              <div key={i} style={{
                display: 'flex', alignItems: 'flex-start', gap: 10, padding: '8px 12px',
                background: C.parchment, border: `1px solid ${C.borderSubtle}`, borderRadius: 8,
                marginBottom: 6,
              }}>
                <span style={{
                  flexShrink: 0, width: 18, height: 18, borderRadius: '50%',
                  border: `1.5px solid ${C.borderStrong}`,
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: F.sans, fontSize: 9.5, fontWeight: 600, color: C.dust,
                }}>{String.fromCharCode(65 + i)}</span>
                <span style={{ fontFamily: F.body, fontSize: 13, color: C.ash, lineHeight: 1.5, minWidth: 0 }}>{opt}</span>
              </div>
            ))}
            <div style={{ fontFamily: F.body, fontSize: 11.5, fontStyle: 'italic', color: C.dust, marginTop: 8 }}>
              The real assessment has more questions, randomised order, and a pass mark of {COURSE_PASS_MARK[course.id]}%.
            </div>
          </div>
        )}

        {/* Legislation */}
        <div style={{ background: C.linen, border: `1px solid ${C.border}`, borderRadius: 8, padding: '14px 16px', marginBottom: 24 }}>
          <Label color={C.dust} mb={6}>Legislation covered</Label>
          <div style={{ fontFamily: F.body, fontSize: 13, color: C.ash, lineHeight: 1.6 }}>{course.legislation}</div>
        </div>

        {/* Certificate */}
        <div style={{ background: C.riverDim, border: `1px solid rgba(61,107,107,0.18)`, borderRadius: 8, padding: '14px 16px', display: 'flex', gap: 12, alignItems: 'center' }}>
          <div style={{ width: 32, height: 32, background: C.river, borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 7l3.5 3.5L12 4" stroke="#fff" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </div>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontFamily: F.sans, fontSize: 11, fontWeight: 600, color: C.river, marginBottom: 2 }}>Certificate on completion</div>
            <div style={{ fontFamily: F.body, fontSize: 12, color: C.ash }}>Named, dated PDF. Downloadable from the dashboard.</div>
          </div>
        </div>
      </div>

      {/* Sticky bottom action bar */}
      <div style={{
        padding: '16px 24px', borderTop: `1px solid ${C.border}`,
        background: C.parchment,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap',
      }}>
        <div style={{ minWidth: 0, flex: '1 1 120px' }}>
          <div style={{ fontFamily: F.sans, fontSize: 9.5, fontWeight: 600, letterSpacing: '1.4px', textTransform: 'uppercase', color: C.dust }}>One licence</div>
          <div style={{ fontFamily: F.display, fontSize: 22, fontWeight: 500, color: C.ink, lineHeight: 1, letterSpacing: '-0.3px' }}>
            £{COURSE_PRICE[course.id] || 17}
            <span style={{ fontFamily: F.body, fontSize: 11, fontWeight: 400, color: C.dust, marginLeft: 4 }}>/ employee</span>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
          <button onClick={() => addToBasket(false)} style={{
            background: 'transparent', color: C.ink,
            border: `1px solid ${C.borderStrong}`, borderRadius: 9999,
            padding: '11px 18px', cursor: 'pointer',
            fontFamily: F.sans, fontSize: 11, fontWeight: 600,
            letterSpacing: '1.4px', textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          }}>+ Add to basket</button>
          <button onClick={() => addToBasket(true)} style={{
            background: C.brass, color: '#fff',
            border: 'none', borderRadius: 9999,
            padding: '11px 20px', cursor: 'pointer',
            fontFamily: F.sans, fontSize: 11, fontWeight: 600,
            letterSpacing: '1.4px', textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          }}>Buy now →</button>
        </div>
      </div>
    </div>
  );
};

const CourseRow = ({ course, onSelect }) => {
  const [hov, setHov] = React.useState(false);
  return (
    <div
      className="tc-course-row"
      role="button"
      tabIndex={0}
      onMouseEnter={() => setHov(true)}
      onMouseLeave={() => setHov(false)}
      onClick={() => onSelect(course)}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') {
          if (e.key === ' ') e.preventDefault(); // stop the page scrolling on space
          onSelect(course);
        }
      }}
      style={{
        display: 'grid', gridTemplateColumns: 'auto 1fr auto auto auto',
        alignItems: 'center', gap: 24,
        padding: '22px 28px',
        cursor: 'pointer',
        background: hov ? C.linen : 'transparent',
        borderBottom: `1px solid ${C.border}`,
        transition: 'background 0.15s',
      }}>
      {/* Tag — fixed height + flex centering with -1px optical lift so uppercase
          text reads as centered (capital letters have no descenders). */}
      <div style={{
        background: C.brassDim, borderRadius: 9999,
        height: 22, padding: '0 12px',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        whiteSpace: 'nowrap', boxSizing: 'border-box',
      }}>
        <span style={{
          fontFamily: F.sans, fontSize: 9, fontWeight: 600,
          letterSpacing: '1.5px', textTransform: 'uppercase', color: C.brass,
          lineHeight: 1, display: 'inline-flex', alignItems: 'center', marginTop: -1,
        }}>{course.tag}</span>
      </div>
      {/* Title */}
      <div style={{ minWidth: 0 }}>
        <Truncate style={{ fontFamily: F.sans, fontSize: 16, fontWeight: 500, color: C.ink, marginBottom: 4 }}>{course.title}</Truncate>
        <Truncate style={{ fontFamily: F.body, fontSize: 13.5, color: C.ash, lineHeight: 1.55, maxWidth: 560 }}>{ROW_BLURB[course.id] || course.desc}</Truncate>
      </div>
      {/* Duration */}
      <div style={{ fontFamily: F.body, fontSize: 13, color: C.ash, whiteSpace: 'nowrap' }}>{course.duration}</div>
      {/* Level */}
      <div style={{ fontFamily: F.body, fontSize: 12.5, color: C.ash, whiteSpace: 'nowrap' }}>{course.level}</div>
      {/* View course link */}
      <div style={{
        fontFamily: F.sans, fontSize: 11, fontWeight: 600,
        letterSpacing: '1.4px', textTransform: 'uppercase',
        color: hov ? C.ink : C.ash,
        whiteSpace: 'nowrap',
        transition: 'color 0.15s',
      }}>
        View course →
      </div>
    </div>
  );
};

/* ── ProgrammeBlock — one renderable section per programme.
   Header strip with kicker, h2 title, intro paragraph and optional filter
   pills; then a course table; then a bundle CTA card. Re-used twice on the
   page so adding a third programme later is a one-block insertion. */
const ProgrammeBlock = ({
  kicker, title, intro, courses,
  filters, filter, onFilter,
  bundleKicker, bundleTitle, bundleSub, bundleCta, onBundleCta,
  onSelect,
  topPad = true,
}) => {
  const filtered = !filters || filter === 'All' ? courses : courses.filter(c => c.tag === filter);
  const filterCount = (f) => f === 'All' ? courses.length : courses.filter(c => c.tag === f).length;

  return (
    <div style={{ maxWidth: 1100, margin: '0 auto', padding: topPad ? '56px clamp(20px, 5vw, 40px) 24px' : '24px clamp(20px, 5vw, 40px) 24px' }}>
      <Label color={C.brass}>{kicker}</Label>
      <h2 style={{ fontFamily: F.display, fontSize: 36, fontWeight: 400, fontStyle: 'italic', color: C.ink, lineHeight: 1.18, letterSpacing: '-0.3px', marginTop: 6, marginBottom: 12 }}>
        {title}
      </h2>
      <p style={{ fontFamily: F.body, fontSize: 16, color: C.ash, lineHeight: 1.65, maxWidth: 620, marginBottom: filters ? 22 : 10 }}>
        {intro}
      </p>

      {filters && (
        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', marginBottom: 8 }}>
          {filters.map(f => {
            const active = filter === f;
            return (
              <button key={f} onClick={() => onFilter(f)} style={{
                background: active ? C.ink : 'transparent',
                color: active ? C.textInverse : C.ash,
                border: `1px solid ${active ? C.ink : C.border}`,
                borderRadius: 9999,
                height: 34, padding: '0 16px', cursor: 'pointer',
                fontFamily: F.sans, fontSize: 11, fontWeight: 600,
                letterSpacing: '1.4px', textTransform: 'uppercase',
                transition: 'all 0.2s',
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                gap: 8, lineHeight: 1, boxSizing: 'border-box',
              }}>
                <span style={{ lineHeight: 1, display: 'inline-flex', alignItems: 'center', marginTop: -1 }}>{f}</span>
                <span style={{
                  fontSize: 10, fontWeight: 600, letterSpacing: '0.5px',
                  color: active ? 'rgba(237,232,223,0.65)' : C.dust,
                  lineHeight: 1, display: 'inline-flex', alignItems: 'center', marginTop: -1,
                }}>{filterCount(f)}</span>
              </button>
            );
          })}
        </div>
      )}

      {/* Course table */}
      <div style={{ marginTop: 18 }}>
        <div className="tc-courses-header" style={{ display: 'grid', gridTemplateColumns: 'auto 1fr auto auto auto', gap: 24, padding: '14px 28px', borderBottom: `1px solid ${C.borderStrong}` }}>
          {['Category', 'Course', 'Duration', 'Suitable for', ''].map(h => (
            <div key={h} style={{ fontFamily: F.sans, fontSize: 10, fontWeight: 600, letterSpacing: '1.6px', textTransform: 'uppercase', color: C.ink }}>{h}</div>
          ))}
        </div>
        {filtered.map(c => <CourseRow key={c.id} course={c} onSelect={onSelect} />)}
      </div>

      {/* Bundle CTA */}
      <div style={{ background: C.ink, borderRadius: 12, padding: 'clamp(20px, 5vw, 36px) clamp(20px, 5vw, 40px)', marginTop: 40, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 32, flexWrap: 'wrap' }}>
        <div>
          <Label color={C.brass} mb={8}>{bundleKicker}</Label>
          <h3 style={{ fontFamily: F.display, fontSize: 26, fontWeight: 400, fontStyle: 'italic', color: C.textInverse, lineHeight: 1.25 }}>
            {bundleTitle}
          </h3>
          <p style={{ fontFamily: F.body, fontSize: 15, color: 'rgba(237,232,223,0.55)', marginTop: 8, maxWidth: 420 }}>
            {bundleSub}
          </p>
        </div>
        <BrassBtn onClick={onBundleCta}>{bundleCta}</BrassBtn>
      </div>
    </div>
  );
};

const CoursesPage = ({ onNav }) => {
  const [foodFilter, setFoodFilter] = React.useState('All');
  const [selected, setSelected] = React.useState(null);

  const foodCourses     = ALL_COURSES.filter(c => c.programme === 'food');
  const dyslexiaCourses = ALL_COURSES.filter(c => c.programme === 'dyslexia');

  return (
    <div style={{ paddingTop: 124, minHeight: '100vh', background: C.parchment }}>
      {/* Hero — sets up both programmes so visitors know what's here before scrolling. */}
      {/* Phone layout for the course table: header hides, each row stacks
          into a two-column card (tag|title / duration|level / CTA spanning).
          Without this the fixed columns crush the 1fr title to zero width. */}
      <style>{`
        @media (max-width: 700px) {
          .tc-courses-header { display: none !important; }
          .tc-course-row { grid-template-columns: auto 1fr !important; gap: 12px 16px !important; align-items: start !important; }
          .tc-course-row > div:nth-child(5) { grid-column: 1 / -1; }
        }
      `}</style>
      <div style={{ background: C.linen, borderBottom: `1px solid ${C.border}`, padding: '56px clamp(20px, 5vw, 40px) 44px' }}>
        <div style={{ maxWidth: 1100, margin: '0 auto' }}>
          <Label color={C.brass}>Course catalogue</Label>
          <h1 style={{ fontFamily: F.display, fontSize: 'clamp(32px, 8vw, 48px)', fontWeight: 400, fontStyle: 'italic', color: C.ink, lineHeight: 1.15, marginTop: 6, marginBottom: 16 }}>
            Two programmes. One Tiber Course.
          </h1>
          <p style={{ fontFamily: F.body, fontSize: 16.5, color: C.ash, lineHeight: 1.70, maxWidth: 620, marginBottom: 22 }}>
            Hospitality compliance training for kitchens and venues — and a separate dyslexia programme for navigating
            school, university, and the workplace. Both UK-aligned. Both with a certificate on completion.
          </p>
          <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap', alignItems: 'center' }}>
            <a href="#food" style={{ fontFamily: F.sans, fontSize: 11, fontWeight: 600, letterSpacing: '1.4px', textTransform: 'uppercase', color: C.ink, textDecoration: 'none', borderBottom: `1px solid ${C.brass}`, paddingBottom: 2 }}>
              Food industry ({foodCourses.length})
            </a>
            <a href="#dyslexia" style={{ fontFamily: F.sans, fontSize: 11, fontWeight: 600, letterSpacing: '1.4px', textTransform: 'uppercase', color: C.ink, textDecoration: 'none', borderBottom: `1px solid ${C.brass}`, paddingBottom: 2 }}>
              Dyslexia programme ({dyslexiaCourses.length})
            </a>
          </div>
        </div>
      </div>

      {/* ── Food industry programme ── */}
      <div id="food" style={{ scrollMarginTop: 96 }}>
        <ProgrammeBlock
          kicker="Food industry · UK hospitality compliance"
          title="Five essentials for any kitchen or venue."
          intro="Fire, food safety, allergens, supervision and first aid — written for the people who actually do the work, and aligned to the legislation an inspector will ask about."
          courses={foodCourses}
          filters={FOOD_FILTERS}
          filter={foodFilter}
          onFilter={setFoodFilter}
          bundleKicker="All five courses included"
          bundleTitle="The hospitality starter pack."
          bundleSub="One subscription. Every essential covered. From £25/month for teams up to 5. Pre-order now — courses launch soon."
          bundleCta="Get the starter pack"
          onBundleCta={() => onNav && onNav('pricing#subscriptions')}
          onSelect={setSelected}
        />
      </div>

      {/* ── Dyslexia programme ── */}
      <div id="dyslexia" style={{ scrollMarginTop: 96 }}>
        <ProgrammeBlock
          kicker="Dyslexia programme · For every life stage"
          title="School. University. The workplace."
          intro="A three-course series written from the inside, for dyslexic learners and the people who teach, mentor, or manage them. Practical strategies, real tools, and the rights you have under the Equality Act."
          courses={dyslexiaCourses}
          bundleKicker="All three courses included"
          bundleTitle="The full dyslexia programme."
          bundleSub="School + University + Workplace. Three licences, £17 each — no subscription required. Pre-order now, save 30%."
          bundleCta="Buy all three"
          onBundleCta={() => {
            // Pre-fill the basket with all three dyslexia courses, then hand off to Pricing.
            try {
              const raw = localStorage.getItem('tc:pending-basket');
              const prev = raw ? JSON.parse(raw) : {};
              prev['dys-school'] = (prev['dys-school'] || 0) + 1;
              prev['dys-uni'] = (prev['dys-uni'] || 0) + 1;
              prev['dys-work'] = (prev['dys-work'] || 0) + 1;
              localStorage.setItem('tc:pending-basket', JSON.stringify(prev));
            } catch (e) {}
            if (onNav) onNav('pricing#individual-courses');
          }}
          onSelect={setSelected}
          topPad={false}
        />
      </div>

      {/* Also from Tiber Course — Lockdubh, the desktop companion that pairs naturally with the dyslexia programme */}
      <SectionWrap linen>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: 24, flexWrap: 'wrap' }}>
          <div style={{ maxWidth: 620 }}>
            <Label color={C.brass}>Also from Tiber Course</Label>
            <h2 style={{ fontFamily: F.display, fontSize: 32, fontWeight: 400, fontStyle: 'italic', color: C.ink, lineHeight: 1.22, letterSpacing: '-0.4px', marginBottom: 14 }}>
              A tool for dyslexic minds.
            </h2>
            <p style={{ fontFamily: F.body, fontSize: 15.5, color: C.ash, lineHeight: 1.70 }}>
              Lockdubh — dictate, read aloud, and chat with a private, on-device AI. Built for the people the dyslexia programme is written for, to use every day at school, at university, and at work.
            </p>
          </div>
          <Btn primary onClick={() => onNav && onNav('lockdubh')}>See Lockdubh →</Btn>
        </div>
      </SectionWrap>

      {/* Slide-out panel */}
      {selected && (
        <>
          <div onClick={() => setSelected(null)} style={{ position: 'fixed', inset: 0, background: 'rgba(26,25,23,0.35)', zIndex: 299, backdropFilter: 'blur(2px)' }} />
          <CourseDetailPanel course={selected} onClose={() => setSelected(null)} onNav={onNav} />
        </>
      )}
    </div>
  );
};

Object.assign(window, { CoursesPage, ALL_COURSES });
