// ===========================================================================
// HUB Training — the guide to using this system, written per role
// ===========================================================================
// Two halves, deliberately separated:
//
//   * The PROSE below is hand-written and describes judgement — what this role
//     is for, the order to do things in, and the traps. It cannot be generated.
//   * The PERMISSION TABLE in each guide is NOT written here. It is rendered
//     live from the role's actual entry in Users -> Role Permissions
//     (roleModuleLevel / roleHasCapability), so a guide can never tell someone
//     they can do something an admin has since switched off. If you change a
//     permission, the training updates itself.
//
// Several roles are permission-identical; those share one guide and say so
// rather than pretending to differ. `roles` on a guide lists every role it
// covers, and `guideForRole()` is the only lookup.
// ---------------------------------------------------------------------------

// Applies to everyone, prepended to every guide.
const TRAINING_COMMON = {
  title: 'Before anything else',
  steps: [
    { t: 'Sign in and set your profile', d: 'Click your avatar, top right. Add a photo and your phone number — the team directory is how people reach you, and a delivery driver on a jobsite will look you up there.' },
    { t: 'Set your notifications', d: 'Same place, under My Notifications. Choose what reaches you in-app and what should also email you. Email queues until the mail service is connected; the in-app inbox works today.' },
    { t: 'Know your department', d: 'LEON runs as two departments — Windows and Interiors. The selector in the header filters the whole app to one of them. If you cover both, use it to cut the noise; if you cover one, the header just tells you which.' },
    { t: 'Learn the Inbox', d: 'The bell shows two different things. ACTIVITY is what happened — someone assigned you work, an approval landed. COMING DUE is recalculated live from your own work every time you open it, so it is never stale. Yellow means within a few days, red means past its date.' },
    { t: 'Get your work into Outlook', d: 'My To-Do and the Inbox both have an export button that produces a calendar file. Open it and your deadlines drop into Outlook. It is a snapshot, not a live sync — re-export when your work changes.' },
  ],
};

// Rewritten 2026-09-04 against the FINAL permission matrix. Every task below
// was checked against what the role can actually edit — if a guide tells someone
// to do something the matrix denies, the guide is the thing that is wrong.
const TRAINING_GUIDES = [
  {
    id: 'admin',
    roles: ['Admin'],
    mission: 'You own the system itself — who is in it, what they can reach, and the standing data every project draws from.',
    startHere: [
      'Read About Us → Company Profile and make sure the legal name, address, tax ID and insurance dates are current. That record prints as "Contractor" on AIA applications, so a stale address goes out on real paperwork.',
      'Open Users → Role Permissions and read the matrix once, end to end, before changing anything.',
      'Open LEON Collection and look at the five tabs — scopes, supplier finishes, materials, lead times, demo data. This is the standing data every project inherits.',
    ],
    daily: [
      'Clear your Inbox — approvals and escalations land there.',
      'Accounting → Job Progress, for scopes where the work has run ahead of the billing.',
    ],
    tasks: [
      { title: 'Add a new employee', when: 'Someone joins', steps: [
        'Users → + Add User.',
        'Set their security role — that drives every permission — then their departments: Windows, Interiors, or both.',
        'Open them from the list and set their job title and who they report to. The title is what shows on the org chart and in the header; the role never does.',
        'Point them at Collection → HUB Training for their own role.',
      ], note: 'Do not use per-user overrides to patch a role that is wrong for everyone. Fix the role.' },
      { title: 'Change what a role can do', when: 'A role is too open or too tight', steps: [
        'Users → Role Permissions. Set each module to None, View or Edit, then tick the capabilities underneath.',
        'Change it for the role, not the person — the next hire inherits it.',
        'Run Reports → User Access Audit afterwards and export it. That is your record of who could do what, and when.',
      ], note: 'Admin\u2019s access to Users is locked on purpose: it is the one switch that cannot be turned off, because turning it off would lock everyone out of the switch.' },
      { title: 'Add a scope family or a finish option', when: 'LEON starts selling something new', steps: [
        'LEON Collection → Scopes & Selections → + Add Scope Family, then add its selection categories and options.',
        'For supplier finishes, go to Supplier Finishes, tick what we carry, and use "Add to a scope selection…" to push them onto the right category in one go.',
      ] },
    ],
    boundaries: [
      'You can see and change everything, which is exactly why you should not be the one doing routine data entry — if you enter it, nobody else learns to.',
    ],
    escalate: ['Nothing escalates past you. Ask Accounting before changing any permission that touches money.'],
    video: { title: 'Admin — running the system', minutes: 12, beats: [
      'Company Profile: what prints on real paperwork, and why insurance expiry dates matter.',
      'Users: add a person, set role, departments, title and reporting line.',
      'Role Permissions: change a role and show it taking effect immediately.',
      'User Access Audit report as the record of the change.',
      'LEON Collection: add a scope family, then batch-add supplier finishes onto it.',
    ] },
  },

  {
    id: 'accounting',
    roles: ['Accounting'],
    mission: 'You hold the cash picture — and in this system you also hold the widest operational reach after Admin.',
    startHere: [
      'Accounting → Financial Calendar. It opens on this week, day by day. Set the opening balance and its date once; every period after opens where the last one closed.',
      'Add standing company costs under Company Income & Expenses — rent, payroll, insurance, utilities. Until they are in, the calendar is optimistic.',
      'Add the company cards under Credit Cards, each with its statement day and due day.',
    ],
    daily: [
      'Financial Calendar in day view: settle what is due, and act on anything yellow or red.',
      'Accounts Payable: approve what is ready, and chase anything stuck at Pending Sales Approval.',
    ],
    tasks: [
      { title: 'Record a client payment', when: 'Money arrives', steps: [
        'Project → Financial Hub → Accounts Receivable, find the payment term, click Record payment.',
        'Enter the date the client actually paid, the amount, and the wire or check reference.',
        'If the bank is holding the deposit, tick "Deposit held by the bank" and lay out the release phases.',
      ], note: 'A held deposit shows on the calendar at $0 on the day the client paid, with the money appearing on the release dates instead. Held money is not cash you have.' },
      { title: 'Set an expected payment date', when: 'You are budgeting', steps: [
        'Same screen. On any unpaid term, set Expected payment. Leave it blank to follow the schedule — the derived date shows in italics.',
      ], note: 'Only you and Admin see this field, and every move of it is logged with your name. There is no silent edit.' },
      { title: 'Move a payment date', when: 'A date slips', steps: [
        'On the Financial Calendar, click Postpone, enter the new date, and say why.',
        'It lands on the project change log and on that invoice\u2019s own history. Reports → Payment Date Change Log shows every move, and counts the ones with no reason given.',
      ] },
      { title: 'Approve an AP invoice', when: 'It reaches you', steps: [
        'Project → Financial Hub → Accounts Payable. Check it against its PO or work order, then approve, request revision, or reject with a reason.',
      ] },
      { title: 'Pay a vendor by card', when: 'Recording an AP payment', steps: [
        'Record the payment and pick the credit card.',
        'The cash does not leave on the invoice date — it rolls into that card\u2019s statement and appears as one payment on the statement due date.',
      ] },
      { title: 'Check the work behind the money', when: 'Before billing, or when a job feels off', steps: [
        'Accounting → Job Progress, switching between Production and Installation.',
        'Read the two bars per row — work complete above, cost paid below — and sort by biggest gap.',
      ] },
    ],
    boundaries: [
      'You can edit Users, which means you can change any role including your own. Treat that as a break-glass power, not a working tool — and log what you change.',
      'A subcontractor invoice sits at Pending Sales Approval until it is released. If the named salesperson cannot reach it, ask Admin or the General Manager to action it.',
    ],
    escalate: ['Admin, for anything about the permission matrix itself.'],
    video: { title: 'Accounting — the cash picture', minutes: 15, beats: [
      'Financial Calendar in day view: reading a week, the flags, the running balance.',
      'Opening balance and per-week overrides.',
      'A receipt, then the same receipt with a bank hold and three release phases — calendar before and after.',
      'Postponing a date, and where the history shows up.',
      'Approving an AP invoice; paying a vendor by card and the statement timing.',
      'Job Progress: the two-bar row and what a wide gap means.',
    ] },
  },

  {
    id: 'gm',
    roles: ['General Manager'],
    mission: 'You run the floor. You can edit almost every operational hub, and you hold the approvals that release money.',
    startHere: [
      'Reports → Project Status by Scope, to learn where every job stands in one page.',
      'Accounting → Job Progress is not open to you; use Reports → Schedule Accuracy and the Executive Portfolio instead.',
    ],
    daily: ['Your Inbox: invoice approvals and AIA certifications.', 'Anything red in Reports.'],
    tasks: [
      { title: 'Approve an AP invoice', when: 'It reaches you', steps: [
        'Project → Financial Hub → Accounts Payable, open the invoice, check it against its PO, then approve or reject with a reason.',
      ], note: 'You can edit Accounts Payable even though the Financial Hub itself is read-only to you — the hub opens, the payables work.' },
      { title: 'Certify an AIA application', when: 'A requisition is ready to bill', steps: [
        'Project → Financial Hub → AIA Billing. Review the schedule of values and the retainage, then certify.',
      ] },
      { title: 'Unblock a stuck job', when: 'Anything stalls', steps: [
        'You can edit Scopes & Schedule, Selections, Shop Drawings, Tasks, Issues, Procurement, Delivery, Export, Installation and Production.',
        'You are the fallback everywhere — which means you are also the bottleneck if people route around their own role. Push it back down when you can.',
      ] },
    ],
    boundaries: ['You see cost and profitability. Most of the company does not — be careful what you paste into a group chat.'],
    escalate: ['Admin for permissions; Accounting for anything about the timing of cash.'],
    video: { title: 'General Manager — approvals and oversight', minutes: 9, beats: [
      'Reports as the morning view.', 'Approving an invoice, including a rejection with a reason.', 'Certifying an AIA application.', 'Where you can step in operationally, and when you should not.',
    ] },
  },

  {
    id: 'pc',
    roles: ['Project Coordinator'],
    mission: 'You keep the job moving: the tasks, the issues, the procurement, and everything happening in the factory and on site.',
    startHere: [
      'Open a project and walk Tasks, Issues, Procurement, Production and Installation — those are the five you own.',
      'Read Scopes & Schedule carefully. You cannot change it, but every date you work to comes from it.',
    ],
    daily: [
      'My To-Do first, then your Inbox.',
      'Anything overdue on your jobs: fix what you own, and escalate the dates you do not.',
    ],
    tasks: [
      { title: 'Raise and chase work', when: 'Continuously', steps: [
        'Project → Tasks → + Add Task, assigned to a person with a due date. It lands in their To-Do and notifies them.',
        'Project → Issues → Respond. Choose Update, Needs Follow-Up, or Resolved — only Resolved closes it.',
        'A follow-up assigned to someone becomes their item, with your due date on it.',
      ] },
      { title: 'Get a date changed', when: 'A stage will slip', steps: [
        'You cannot edit Scopes & Schedule. Raise it with the Production Director, or the General Manager or Admin.',
        'Say what moved, by how many days, and why — they enter the delay and everything downstream shifts automatically.',
      ], note: 'Report it the day you learn it. A delay entered a week late has already misled everyone who read the schedule in between.' },
      { title: 'Run procurement on a scope', when: 'Material needs ordering', steps: [
        'Project → Procurement Hub. You can create and edit purchase orders and proforma invoices.',
        'Check the vendor estimate first, then convert it — Reports → Estimate vs PO Variance shows where those drift apart.',
      ], note: 'You can commit spend but you cannot see cost or margin figures. If a number matters to the decision, ask Accounting.' },
      { title: 'Run the field', when: 'Install and closeout', steps: [
        'Project → Production Hub for factory status; Installation Hub for measurements, installs, punch and daily reports.',
        'Punch items marked complete come to you to verify. Check the photo, then close it or send it back.',
      ] },
    ],
    boundaries: [
      'You cannot edit Scopes & Schedule, Selections, Shop Drawings, Contacts, Project Information or the Delivery Hub — all read-only to you.',
      'You see no cost, margin or invoice figures.',
    ],
    escalate: ['Production Director for schedule and factory; Logistic Manager for anything moving; Accounting for money; Admin or GM for anything blocked.'],
    video: { title: 'Project Coordinator — keeping the job moving', minutes: 12, beats: [
      'Tasks and the issue response flow, including a follow-up hand-off.',
      'Reading the schedule you do not own, and how to escalate a slip.',
      'Procurement: estimate to PO.',
      'Production status and the installation close-out loop, ending on punch verification.',
    ] },
  },

  {
    id: 'production',
    roles: ['Production Director'],
    mission: 'You own the schedule and the factories — what is being made, when it will be ready, and what every downstream date depends on.',
    startHere: [
      'Project → Scopes & Schedule. You are one of the three people who can change it, so learn it properly.',
      'LEON Collection → Lead Times, to understand the durations every schedule is built from.',
    ],
    daily: ['Production records that should have started and have not.', 'Delay reports coming in from coordinators.'],
    tasks: [
      { title: 'Record a delay', when: 'A stage slips', steps: [
        'Project → Scopes & Schedule, open the stage, enter the delay in days with a reason.',
        'Everything downstream shifts automatically; nothing upstream moves.',
      ], note: 'Coordinators cannot do this — they will bring slips to you. Enter them the day you hear them.' },
      { title: 'Add a scope to a job', when: 'A job is sold', steps: [
        'Project → Scopes & Schedule → + Add Scope. Pick the family; stages and durations come from the lead-time library.',
        'Choose whether you are setting a start date or a required jobsite date — a jobsite date schedules backwards.',
        'A Window / Exterior Door System family also asks for the system, finish and glass, and builds its own approval-driven schedule.',
      ] },
      { title: 'Move a production record forward', when: 'The factory starts or finishes', steps: [
        'Project → Production → open the record → set the status.',
        'In Production stamps the start date; Complete stamps completion. Both feed the schedule.',
      ] },
      { title: 'Post drawings, photos or a QC report', when: 'Whenever the factory sends something', steps: [
        'Open the record and upload into the right list. Uploading never overwrites — it adds a revision and supersedes the previous one.',
      ] },
      { title: 'Tune the lead times', when: 'Quarterly, or when jobs keep running late', steps: [
        'Reports → Schedule Accuracy & Lead-Time Variance, grouped by stage.',
        'A stage that is consistently late means the library is wrong, not the projects. Ask Admin to adjust it in LEON Collection.',
      ] },
    ],
    boundaries: ['You can commit spend through Procurement but you cannot see cost figures. Ask Accounting for a number.'],
    escalate: ['Project Coordinator so the field knows; Export Manager when a date affects a shipment.'],
    video: { title: 'Production Director — the schedule and the factory', minutes: 11, beats: [
      'Adding a scope; start-date vs jobsite-date scheduling.',
      'Recording a delay and watching the cascade — and why only you can.',
      'Production records, statuses, and revision history on drawings and QC.',
      'Schedule Accuracy report and tuning the lead-time library.',
    ] },
  },

  {
    id: 'senior-associate',
    roles: ['Senior Associate'],
    mission: 'You carry the client\u2019s selections and the drawings that come from them, and you can buy the material they specify.',
    startHere: [
      'Project → Selection Hub. You are one of the few who can edit it — it is the record of what the client actually chose.',
      'LEON Library → Supplier Finishes, so you know what we can offer before you offer it.',
    ],
    daily: ['Selections still open on your jobs.', 'Issues assigned to you, and your Inbox.'],
    tasks: [
      { title: 'Work a client\u2019s selections', when: 'Through design', steps: [
        'Project → Selections. Set an application area for each group, then choose an option per category.',
        'Attach a supplier finish where the client picked a real product.',
        'Locking the selections captures a numbered revision — the first lock is Revision 1, and only a lock after a reopened revision request becomes Revision 2.',
      ], note: 'Revisions are keyed to lock events, not to every edit. That is deliberate: it is the client sign-off that matters.' },
      { title: 'Get material ordered for a scope', when: 'Selections are firm', steps: [
        'Project → Procurement Hub. You can READ the estimates, purchase orders and proforma invoices on your jobs, and see what has been committed.',
        'You cannot raise or edit one. Send the scope, the finish and the quantity to the Project Coordinator, who does.',
      ], note: 'You can see the money on your jobs — cost, price and margin. Use it; sales is measured on it. What you cannot do is commit spend.' },
      { title: 'Answer an issue', when: 'One lands on your job', steps: [
        'Project → Issues → Respond. Update, Needs Follow-Up, or Resolved — only Resolved closes it.',
      ] },
      { title: 'Get a quote or change order raised', when: 'The client asks for something outside the contract', steps: [
        'Open the Sales Hub and read the current quotation and contract value first, so you know what is already in it.',
        'You cannot edit it. Send the scope and the client\u2019s request to Accounting or Admin, who raise it.',
        'An approved change order lifts the revised contract value the payment terms are calculated against.',
      ] },
    ],
    boundaries: [
      'You can READ the Financial Hub, Profitability, the Sales Hub and Accounts Payable — the numbers on your own jobs are yours to look at. You cannot change any of them.',
      'You cannot raise or edit a purchase order, a quotation or a change order. You read them and ask the person who owns them.',
      'Project Information is readable but its fields are locked to you — the Project Coordinator and above own that record.',
    ],
    escalate: ['Project Coordinator for dates, purchase orders and field work; Accounting for quotes, contracts and change orders.'],
    video: { title: 'Senior Associate — selections to purchase', minutes: 10, beats: [
      'The Selection Hub: application areas, options, supplier finishes.',
      'Locking selections and the revision history.',
      'Procurement: raising a PO from an estimate.',
      'Answering an issue, and what to hand to Accounting.',
    ] },
  },

  {
    id: 'associates',
    roles: ['Associates'],
    mission: 'You produce and maintain the drawings, take-offs and renders a job runs on, and you answer the issues raised against them. Your access is identical to a Senior Associate\u2019s — the difference between the two is seniority and what you are handed, not what the system will let you open.',
    startHere: [
      'Project → Shop Drawing Hub and Drawing Sets — the two you will live in.',
      'Project → Take-offs Hub, including the Excel import.',
    ],
    daily: ['Your To-Do and Inbox.', 'Submittals waiting on a revision.'],
    tasks: [
      { title: 'Post a shop drawing revision', when: 'A drawing changes', steps: [
        'Project → Shop Drawing Hub, open the thread, add a revision with the file.',
        'Uploading never overwrites — the previous revision is kept and marked superseded.',
      ] },
      { title: 'Import a take-off from Excel', when: 'A take-off arrives as a spreadsheet', steps: [
        'Project → Take-offs Hub → import. It reads item number, item name, description, quantity, width/height/depth and thickness.',
        'A row survives if it has any of description, name or code — check what came in and delete the rows that are noise before saving.',
      ] },
      { title: 'Answer an issue', when: 'One is raised on your work', steps: [
        'Project → Issues → Respond. Update, Needs Follow-Up, or Resolved — only Resolved closes it.',
        'Attach the drawing or photo that settles it.',
      ] },
    ],
    boundaries: [
      'You can READ the Financial Hub, Profitability, the Sales Hub and Accounts Payable on your jobs. You cannot change any of them.',
      'You cannot raise or edit a purchase order — Procurement is read-only to you.',
      'Project Information is readable but its fields are locked to you.',
    ],
    escalate: ['Senior Associate for selections; Project Coordinator for dates, purchase orders and site questions.'],
    video: { title: 'Associates — drawings, take-offs and issues', minutes: 9, beats: [
      'Shop drawing revisions and why nothing is overwritten.',
      'The Excel take-off import, field by field, and cleaning the result.',
      'Renders and drawing sets.',
      'Answering an issue well.',
    ] },
  },

  {
    id: 'junior-associate',
    roles: ['Junior Associate'],
    mission: 'You draft: shop drawings, drawing sets, take-offs and selections. Most of the rest of the job you can read — including the money on it — but not change.',
    startHere: [
      'Project → Shop Drawing Hub and Drawing Sets.',
      'Project → Take-offs Hub and its Excel import.',
    ],
    daily: ['Your To-Do and Inbox.'],
    tasks: [
      { title: 'Post a drawing revision', when: 'A drawing changes', steps: [
        'Project → Shop Drawing Hub, open the thread, add a revision with the file. The previous revision is kept and superseded.',
      ] },
      { title: 'Import a take-off from Excel', when: 'A take-off arrives as a spreadsheet', steps: [
        'Project → Take-offs Hub → import, then review what came in and delete the noise rows before saving.',
      ] },
      { title: 'Pick up a task', when: 'One is assigned to you', steps: [
        'My To-Do, or your Inbox. Mark it complete when it is done — the person who assigned it is watching that, not their email.',
      ] },
    ],
    boundaries: [
      'You CAN edit Selections — that is part of your work. Issues you read: raise anything you find with an Associate or the Project Coordinator.',
      'You can read the Financial Hub, Profitability and the Sales Hub. You cannot change them, and you cannot raise a purchase order.',
      'Project Information and Contacts are read-only to you.',
    ],
    escalate: ['Associates or Senior Associate on your own work; Project Coordinator for anything about the job.'],
    video: { title: 'Junior Associate — drafting in the hub', minutes: 7, beats: [
      'Where your work lives.', 'A drawing revision.', 'The take-off import.', 'Working your To-Do.',
    ] },
  },

  {
    id: 'export',
    roles: ['Export Manager'],
    mission: 'You get material out of the factory and into the country, with the paperwork intact.',
    startHere: [
      'Logistics → Export Hub. A container is the unit of work.',
      'Open a container and read its Documents checklist — nine steps, each either a file or a Not-Required toggle.',
    ],
    daily: ['Containers in transit and their tracking links.', 'Document steps still missing on anything about to sail.'],
    tasks: [
      { title: 'Build a container', when: 'Material is ready to ship', steps: [
        'Export Hub → new container. Add material lines; each carries its project and scope, and lines group themselves project → scope → items so a mixed container still reads clearly.',
      ] },
      { title: 'Work the document checklist', when: 'Throughout the shipment', steps: [
        'Upload each document as it exists. If a step genuinely does not apply, mark it Not Required rather than leaving it blank.',
        'Completeness counts a step as done if it has a file OR is marked not required. Reports → Export Document Completeness shows what is still open.',
      ] },
      { title: 'Receive at the warehouse', when: 'The container lands', steps: [
        'Open the container and use Receive at Warehouse. Customs entry, duty and the delivery POD are captured there, not on the container card.',
      ] },
      { title: 'Approve freight', when: 'A freight estimate needs releasing', steps: [
        'You hold the export-side freight approval. Admin or Accounting holds the other side — both are needed.',
      ] },
    ],
    boundaries: [
      'Export Hub and Logistics are the only two things you can edit. Tasks, drawings and the Installation Hub are closed or read-only.',
      'You see no financial figures.',
    ],
    escalate: ['Logistic Manager once material is in country; Accounting for freight invoices.'],
    video: { title: 'Export Manager — container to warehouse', minutes: 10, beats: [
      'Building a container with multi-project lines.',
      'The document checklist and the Not-Required toggle.',
      'Receiving at the warehouse and where customs data goes.',
      'The two-sided freight approval.',
    ] },
  },

  {
    id: 'logistics',
    roles: ['Logistic Manager'],
    mission: 'You know where every piece of material is, and you get it to site on the day it is needed.',
    startHere: ['Inventory — warehouses, stock, allocations.', 'Logistics → Delivery and Dispatch.'],
    daily: ['Deliveries scheduled for today and tomorrow.', 'Allocation and delivery requests waiting on your approval.'],
    tasks: [
      { title: 'Schedule a delivery', when: 'Material is needed on site', steps: [
        'Create the delivery and set the destination type — Jobsite, Subcontractor, Warehouse or Client.',
        'Add the lines; they group by scope so the driver and the crew read the same thing.',
        'Assign a driver and truck.',
      ] },
      { title: 'Approve a delivery request', when: 'One is raised', steps: [
        'You hold delivery approval, and you can override a delivery status when reality disagrees with the system.',
      ] },
      { title: 'Allocate material to a job', when: 'Stock is committed', steps: [
        'Inventory → Allocations. Allocate from the warehouse to the project and scope.',
        'Leftover material can be converted back to stock — that needs both Admin and you.',
      ] },
    ],
    boundaries: [
      'Delivery, Logistics and Inventory are yours to edit; the project hubs are not.',
      'You see no financial figures.',
    ],
    escalate: ['Project Coordinator when a delivery date has to move; Export Manager for anything still in transit.'],
    video: { title: 'Logistic Manager — stock to site', minutes: 10, beats: [
      'Warehouse stock and allocation.',
      'Building a delivery with grouped lines and a destination type.',
      'Driver assignment and dispatch.',
      'Approving a request; converting leftovers back to stock.',
    ] },
  },

  {
    id: 'field',
    roles: ['Installation Team & Field Foreman'],
    mission: 'You install the work and you are the eyes on site. What you record is what the office knows.',
    startHere: ['Project → Installation Hub. The subtabs run in the order the work does: Measurements, Installation, Punch List, Daily Report, Field Issues.'],
    daily: ['Your To-Do for today.', 'Close out yesterday: photos, completion, punch items.'],
    tasks: [
      { title: 'Record a measurement or template', when: 'You measure on site', steps: [
        'Installation → Measurements.',
        'Say whether you measured a ROUGH OPENING or FINISHED WALLS.',
      ], note: 'Getting that wrong causes a re-fabrication — the allowance for finishes is either still to come off or already gone.' },
      { title: 'Work an installation record', when: 'On site', steps: [
        'Move the status along as the work goes, and set percent complete if it is partial.',
        'Photos go on the record, not in a text message.',
      ] },
      { title: 'Raise a field issue', when: 'Something is wrong', steps: [
        'Installation → Field Issues. Pick the type and urgency, attach a photo.',
        'Say what you need, not just what is wrong. "Missing 4 panels, cannot finish unit 12B" beats "material problem".',
      ] },
    ],
    boundaries: [
      'The Installation Hub is the only thing you can edit. You see no money anywhere.',
      'A punch item you mark complete goes to the Project Coordinator to verify — you cannot close it yourself.',
    ],
    escalate: ['Project Coordinator for anything that changes a date or a scope.'],
    video: { title: 'Field — install, record, close out', minutes: 9, beats: [
      'The Installation Hub in work order.',
      'Rough opening vs finished walls, and why it matters.',
      'Photos and completion.',
      'Raising a useful field issue.',
    ] },
  },

  {
    id: 'subcontractor',
    roles: ['Subcontractor'],
    mission: 'You see only your own assigned work, and you submit your invoices through it.',
    startHere: ['Your portal shows the jobs you are assigned to and nothing else.'],
    daily: ['Your assigned installations and measurements.'],
    tasks: [
      { title: 'Submit an invoice', when: 'You have completed work', steps: [
        'Submit against the project. One invoice can cover several projects — it splits into one record per project but stays one invoice to you.',
        'It is reviewed before Accounting can pay it.',
      ], note: 'If it shows Pending Sales Approval, it is waiting on LEON\u2019s side, not on you. Chase your Project Coordinator.' },
      { title: 'Report from site', when: 'Every visit', steps: ['Record the work, add photos, and raise a field issue if something is blocking you.'] },
    ],
    boundaries: ['You cannot see other subcontractors\u2019 work, any cost figure, or any project you are not assigned to.'],
    escalate: ['Your Project Coordinator.'],
    video: { title: 'Subcontractor portal', minutes: 6, beats: ['What you can see.', 'Recording work and photos.', 'Submitting an invoice and the approval route.'] },
  },

  {
    id: 'driver',
    roles: ['Delivery Driver'],
    mission: 'You run the deliveries assigned to you and capture proof they happened.',
    startHere: ['Your hub lists only the deliveries assigned to you.'],
    daily: ['Today\u2019s runs, in order.'],
    tasks: [
      { title: 'Complete a delivery', when: 'On arrival', steps: [
        'Open the delivery and check the lines against what is on the truck.',
        'Capture the proof of delivery — signature and photos — before you leave site.',
      ], note: 'Proof captured on site is worth ten times proof reconstructed later.' },
    ],
    boundaries: ['You see deliveries, not projects, and no money.'],
    escalate: ['Logistic Manager.'],
    video: { title: 'Delivery Driver hub', minutes: 5, beats: ['Your run list.', 'Checking lines.', 'Capturing proof of delivery.'] },
  },

  {
    id: 'client',
    roles: ['Client'],
    mission: 'You follow your own job\u2019s progress and approve your selections.',
    startHere: ['Your portal shows only your project.'],
    daily: [],
    tasks: [
      { title: 'Approve selections', when: 'Your coordinator asks', steps: [
        'Open the selections and confirm each one.',
        'Once locked, a change is a formal revision request — the numbered revision history is what everyone works from.',
      ] },
      { title: 'Follow progress', when: 'Any time', steps: ['Switch between the list and timeline views. Past deliveries are shown as well as upcoming ones.'] },
    ],
    boundaries: ['You see your project only, and no cost or margin figures.'],
    escalate: ['Your LEON contact.'],
    video: { title: 'Client portal', minutes: 5, beats: ['Progress as list or timeline.', 'Approving selections and the revision flow.', 'Deliveries and documents.'] },
  },

  {
    id: 'qc-inspector',
    roles: ['QC Inspector'],
    mission: 'You inspect the work and record what you found. Your finding is the record — nobody else can change it.',
    startHere: [
      'Signing in takes you straight to My Inspections. There is no other screen: you do not see projects, schedules, money or anybody else\u2019s work.',
      'Read the two lists — To do, and what you have already recorded. They are ordered by the date each was booked for.',
    ],
    daily: ['Work through To do. Anything still listed is still outstanding.'],
    tasks: [
      { title: 'Carry out an inspection', when: 'One is booked in your name', steps: [
        'Open it from To do. The area it covers and the checks to make are already on it.',
        'Mark each check as you go, and add photos where a photo says it better than a sentence.',
        'Choose the result: Passed, Passed with Notes, or Failed.',
        'Write the note. Anything other than a clean pass will not submit without one \u2014 that is deliberate, because the shop has to know what to act on.',
      ], note: 'Once recorded, the result is fixed and shows as yours. A coordinator can read it; they cannot change it.' },
      { title: 'Inspect for a third party', when: 'You are not LEON staff', steps: [
        'Nothing changes. An in-house inspection and a third-party one are the same record with a different person on it, so the job\u2019s QC history reads the same however it was done.',
      ] },
      { title: 'Raise something outside the inspection', when: 'You see a problem that is not on the checklist', steps: [
        'Put it in the note and fail or flag the inspection. You cannot open an Issue yourself \u2014 the coordinator raises it from your finding.',
      ] },
    ],
    boundaries: [
      'You see the inspections booked in your name and nothing else \u2014 no project list, no drawings, no schedule, no money.',
      'You cannot book your own inspection; the coordinator books it and assigns it to you.',
      'You cannot re-open a result once it is recorded. Say what you found the first time.',
    ],
    escalate: ['The Project Coordinator who booked the inspection. Anything urgent on site goes to them, not into the note alone.'],
    video: { title: 'QC Inspector \u2014 recording an inspection', minutes: 5, beats: [
      'Signing in: what the portal is, and what it deliberately is not.',
      'Opening an inspection and working the checks.',
      'Photos, and why they matter more than adjectives.',
      'The three results, and why anything short of a clean pass demands a note.',
      'What happens to your finding afterwards \u2014 who reads it, and that nobody can edit it.',
    ] },
  },
];

function guideForRole(role) {
  return TRAINING_GUIDES.find(g => g.roles.includes(role)) || null;
}
