"""Generate focused analysis-comparison PDFs for Intesar's essays."""

from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.lib.colors import HexColor
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)
import os

NAVY      = HexColor("#1a2744")
GOLD      = HexColor("#c9a227")
MED_TEXT  = HexColor("#2d3748")
LIGHT_TEXT = HexColor("#4a5568")
BORDER    = HexColor("#d4cfc5")
WARM_BG   = HexColor("#fdf6ee")
COOL_BG   = HexColor("#eef5ee")
ACTION_BG = HexColor("#f0f4ff")
REWRITE_BEFORE = HexColor("#fce8e8")
REWRITE_AFTER  = HexColor("#e2f0e2")

def make_styles():
    s = {}
    s["title"] = ParagraphStyle("title", fontName="Helvetica-Bold", fontSize=15,
        textColor=NAVY, alignment=TA_LEFT, spaceAfter=1, leading=18)
    s["subtitle"] = ParagraphStyle("subtitle", fontName="Helvetica", fontSize=9,
        textColor=LIGHT_TEXT, alignment=TA_LEFT, spaceAfter=8, leading=11)
    s["h1"] = ParagraphStyle("h1", fontName="Helvetica-Bold", fontSize=11,
        textColor=NAVY, spaceBefore=10, spaceAfter=3, leading=13)
    s["h2"] = ParagraphStyle("h2", fontName="Helvetica-Bold", fontSize=9,
        textColor=MED_TEXT, spaceBefore=5, spaceAfter=2, leading=11)
    s["body"] = ParagraphStyle("body", fontName="Helvetica", fontSize=8.5,
        textColor=MED_TEXT, alignment=TA_JUSTIFY, leading=11.5,
        spaceBefore=1, spaceAfter=3)
    s["essay"] = ParagraphStyle("essay", fontName="Helvetica", fontSize=8,
        textColor=HexColor("#374151"), alignment=TA_JUSTIFY, leading=10.5)
    s["action"] = ParagraphStyle("action", fontName="Helvetica", fontSize=8.5,
        textColor=HexColor("#1e3a5f"), alignment=TA_LEFT, leading=11.5,
        spaceBefore=1, spaceAfter=1)
    s["rewrite_label"] = ParagraphStyle("rewrite_label", fontName="Helvetica-Bold",
        fontSize=7.5, textColor=LIGHT_TEXT, leading=10, spaceBefore=0, spaceAfter=1)
    s["rewrite"] = ParagraphStyle("rewrite", fontName="Helvetica", fontSize=8,
        textColor=MED_TEXT, alignment=TA_JUSTIFY, leading=10.5)
    s["footer"] = ParagraphStyle("footer", fontName="Helvetica", fontSize=7,
        textColor=LIGHT_TEXT, alignment=TA_LEFT, leading=9)
    return s

ST = make_styles()

def shaded(text, bg, pad=6):
    t = Table([[Paragraph(text, ST["essay"])]], colWidths=["100%"])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("LEFTPADDING", (0,0), (-1,-1), pad), ("RIGHTPADDING", (0,0), (-1,-1), pad),
        ("TOPPADDING", (0,0), (-1,-1), pad), ("BOTTOMPADDING", (0,0), (-1,-1), pad),
        ("BOX", (0,0), (-1,-1), 0.3, BORDER),
    ]))
    return t

def action_box(text):
    t = Table([[Paragraph(text, ST["action"])]], colWidths=["100%"])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), ACTION_BG),
        ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 8),
        ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ]))
    return t

def rewrite_pair(before_text, after_text):
    before_parts = [
        [Paragraph("<b>CONCLUSORY</b>", ST["rewrite_label"]),
         Paragraph(before_text, ST["rewrite"])]
    ]
    after_parts = [
        [Paragraph("<b>REWRITTEN</b>", ST["rewrite_label"]),
         Paragraph(after_text, ST["rewrite"])]
    ]
    bt = Table(before_parts, colWidths=["100%"])
    bt.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), REWRITE_BEFORE),
        ("LEFTPADDING", (0,0), (-1,-1), 6), ("RIGHTPADDING", (0,0), (-1,-1), 6),
        ("TOPPADDING", (0,0), (-1,-1), 4), ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("BOX", (0,0), (-1,-1), 0.3, BORDER),
    ]))
    at = Table(after_parts, colWidths=["100%"])
    at.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), REWRITE_AFTER),
        ("LEFTPADDING", (0,0), (-1,-1), 6), ("RIGHTPADDING", (0,0), (-1,-1), 6),
        ("TOPPADDING", (0,0), (-1,-1), 4), ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("BOX", (0,0), (-1,-1), 0.3, BORDER),
    ]))
    return [bt, Spacer(1, 2), at, Spacer(1, 6)]

def thin_hr():
    return HRFlowable(width="100%", thickness=0.4, color=BORDER, spaceAfter=3, spaceBefore=4)

def gold_hr():
    return HRFlowable(width="25%", thickness=1, color=GOLD, spaceAfter=4, spaceBefore=2)


# =====================================================================
# BUSINESS ASSOCIATIONS
# =====================================================================
def build_business_associations():
    output_dir = r"C:\Users\sallen\Desktop\SHEP\BAR PREP by SHEP\STUDENT ANSWERS\Intesar"
    output_path = os.path.join(output_dir, "Intesar_Business-Associations_v2.pdf")
    doc = SimpleDocTemplate(output_path, pagesize=letter,
        leftMargin=0.65*inch, rightMargin=0.65*inch,
        topMargin=0.55*inch, bottomMargin=0.5*inch)
    story = []

    story.append(Paragraph("Deepening Your Analysis: Business Associations", ST["title"]))
    story.append(gold_hr())
    story.append(Paragraph("Intesar S.  |  Band 4/6  |  May 19, 2026", ST["subtitle"]))
    story.append(Paragraph(
        "On the bar exam, <b>analysis</b> is where you earn the most points. The rule statement "
        "shows you know the law. The analysis shows you can <i>use</i> it. Analysis means taking "
        "the specific facts from the prompt and explaining, step by step, why they satisfy or fail "
        "each element of the rule. A conclusion without this reasoning is just an assertion -- the "
        "grader has no evidence you understood the problem. Below, we compare the analysis portions "
        "of your essay against a model answer, with specific ways to strengthen each one.",
        ST["body"]))
    story.append(Spacer(1, 2))

    # Issue 1
    story.append(thin_hr())
    story.append(Paragraph("Issue 1: Carol's Authority to Bind the Partnership", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "Carol was hired as a sales manager, and the partnership explicitly told her she could "
        "approve custom orders only up to $5,000. However, last month, the partnership allowed "
        "a $5,500 contract to proceed without comment. Carol's $7,000 contract fails under actual "
        "authority because Carol does not have actual authority to exceed the $5,000 limit, despite "
        "the previous $5,500 contract. Therefore, the contract does not bind the partnership.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "Carol lacked actual authority. A&amp;B explicitly told her she could only approve orders "
        "up to $5,000. However, Carol likely had apparent authority. A&amp;B's prior conduct -- "
        "allowing the $5,500 contract to proceed without comment -- was a manifestation to the "
        "public. A new client like Dave could reasonably believe, based on A&amp;B's past "
        "acquiescence to an over-the-limit contract, that Carol had the authority to enter into "
        "similar contracts. The principal's manifestation, not the agent's, creates apparent "
        "authority. Therefore, A&amp;B Designs is bound.",
        COOL_BG))
    story.append(Paragraph(
        "You correctly applied the $5,000 limit to show actual authority fails. But you stopped "
        "there. The $5,500 contract is the most important fact in this question -- it exists to "
        "trigger a second theory: apparent authority. You mentioned it but dismissed it. The model "
        "uses it as the crux: the partnership's silence told outsiders like Dave that Carol could "
        "approve larger deals. When one theory fails, the exam is almost always testing whether "
        "you will spot the next one.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> Every time you write \"therefore, this fails,\" pause and ask: "
        "do the facts support an alternative theory that succeeds? Write two sentences on it, "
        "even if brief. That is where the points are."))

    # Issue 2
    story.append(thin_hr())
    story.append(Paragraph("Issue 2: Partnership Liability for the Showroom Lease", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "Ben, despite not consulting Alice, signed a one-year lease for a large new showroom "
        "with Landlord Corp. The lease will likely bind the partnership because Ben was acting "
        "within the ordinary course of business dealings and did not exceed his actual authority.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "Ben, a partner, signed a lease for a showroom. For a business that creates and sells "
        "custom furniture, having a showroom is squarely within the ordinary course of business. "
        "It is not an extraordinary matter requiring a unanimous vote of the partners. Because "
        "the act was in the ordinary course, Ben had the authority to bind the partnership.",
        COOL_BG))
    story.append(Paragraph(
        "You reached the right answer. The gap is one missing sentence: <i>why</i> is a showroom "
        "lease \"ordinary course\"? You asserted it. The model explains it -- a furniture design "
        "firm needs a showroom to display products, so leasing one is routine. That single "
        "explanatory sentence turns an assertion into analysis.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> After every conclusion, add one sentence starting with "
        "\"because\" that ties it to the specific facts. \"This is ordinary course <i>because</i> "
        "a furniture firm needs a showroom\" -- that is the analysis."))

    # Issue 3
    story.append(thin_hr())
    story.append(Paragraph("Issue 3: Ben's Duty of Loyalty (Van Sale)", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "Ben proposed that the corporation buy the van for $30,000, providing the material facts "
        "by disclosing his ownership of the dealership and presenting reliable data showing the "
        "price is fair market value, and the majority of disinterested directors voted in favor "
        "when Alice reviewed the data and voted to approve the purchase.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "The van sale was a classic conflicting interest transaction because Ben stood on both "
        "sides: as a director of the buyer and as the sole owner of the seller. However, Ben "
        "followed the disinterested director safe harbor. He disclosed the material facts and "
        "his interest to the board. Alice was disinterested as she had no financial stake in "
        "Ben's dealership. After reviewing data, Alice voted to approve. This cleansed the "
        "transaction.",
        COOL_BG))
    story.append(Paragraph(
        "This is your strongest section -- you identified the right elements, applied each to "
        "the facts, and reached the correct conclusion. The one difference: the model names the "
        "problem before solving it. \"Ben stood on both sides\" tells the reader <i>why</i> the "
        "duty of loyalty is triggered. You jumped straight into the safe harbor without explaining "
        "what made this transaction suspicious. Setting up the conflict first makes your resolution "
        "more persuasive.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> Before applying a legal test, write one sentence identifying "
        "what makes this situation <i>problematic</i>. \"This is a conflict because Ben is on "
        "both sides of the deal\" -- then the safe harbor analysis lands with more force."))

    # Conclusory vs Proper
    story.append(Spacer(1, 4))
    story.append(HRFlowable(width="100%", thickness=0.8, color=GOLD, spaceAfter=4, spaceBefore=6))
    story.append(Paragraph("Conclusory Analysis vs. Proper Analysis", ST["h1"]))
    story.append(Paragraph(
        "Below are specific sentences from your essay rewritten to show the difference. "
        "The conclusory version states the outcome. The rewritten version explains <i>why</i> "
        "the facts lead there.",
        ST["body"]))

    # Rewrite 1
    story.append(Paragraph("<i>Issue 1 -- The $5,500 contract</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "Carol's $7,000 contract fails under actual authority because Carol does not have "
        "actual authority to exceed the $5,000 limit, despite the previous $5,500 contract "
        "that was allowed.",
        "Carol lacked actual authority because the partnership capped her at $5,000. However, "
        "by letting the $5,500 contract proceed without objection, the partnership signaled to "
        "outsiders that Carol could approve larger deals. Dave, a new client, could reasonably "
        "believe Carol had authority -- and that appearance binds the partnership."
    ))

    # Rewrite 2
    story.append(Paragraph("<i>Issue 2 -- Ordinary course of business</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "The lease will likely bind the partnership because Ben was acting within the ordinary "
        "course of business dealings and did not exceed his actual authority.",
        "The lease binds the partnership because a custom furniture business needs a showroom "
        "to display its products -- leasing one is a routine business need, not an extraordinary "
        "decision requiring both partners' consent."
    ))

    # Rewrite 3
    story.append(Paragraph("<i>Issue 2 -- Alice's personal liability</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "Alice is personally liable on the showroom lease because the general partnership "
        "creates a joint and several liability to the partnership.",
        "Alice is jointly and severally liable because she is a general partner -- Landlord "
        "Corp. could pursue her personally for the full lease amount, even though she never "
        "agreed to it."
    ))

    # Rewrite 4
    story.append(Paragraph("<i>Issue 3 -- Self-dealing setup</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "Ben proposed that the corporation buy the van for $30,000, providing the material "
        "facts by disclosing his ownership of the dealership.",
        "This is a self-dealing transaction because Ben stands on both sides -- director of "
        "the buyer and owner of the seller. However, he disclosed his interest and ownership "
        "to the board before the vote."
    ))

    # Closing
    story.append(HRFlowable(width="100%", thickness=0.4, color=BORDER, spaceAfter=4, spaceBefore=6))
    story.append(Paragraph(
        "You already know the law. Your issue spotting is complete and your conclusions are almost "
        "always correct. The gap between a 4 and a 6 is showing more of your reasoning on the "
        "page: (1) when one theory fails, look for a second one; (2) after every conclusion, "
        "add a \"because\" sentence tied to the specific facts; (3) name the problem before you "
        "solve it. These are small changes that compound.",
        ST["body"]))
    story.append(Spacer(1, 10))
    story.append(Paragraph("Bar Prep by SHEP  |  May 19, 2026", ST["footer"]))
    doc.build(story)
    return output_path


# =====================================================================
# REAL PROPERTY
# =====================================================================
def build_real_property():
    output_dir = r"C:\Users\sallen\Desktop\SHEP\BAR PREP by SHEP\STUDENT ANSWERS\Intesar"
    output_path = os.path.join(output_dir, "Intesar_Real-Property_v2.pdf")
    doc = SimpleDocTemplate(output_path, pagesize=letter,
        leftMargin=0.65*inch, rightMargin=0.65*inch,
        topMargin=0.55*inch, bottomMargin=0.5*inch)
    story = []

    story.append(Paragraph("Deepening Your Analysis: Real Property", ST["title"]))
    story.append(gold_hr())
    story.append(Paragraph("Intesar S.  |  Band 3/6  |  May 14, 2026", ST["subtitle"]))
    story.append(Paragraph(
        "On the bar exam, <b>analysis</b> is where you earn the most points. The rule statement "
        "shows you know the law. The analysis shows you can <i>use</i> it. Analysis means taking "
        "the specific facts from the prompt and explaining, step by step, why they satisfy or fail "
        "each element of the rule. A conclusion without this reasoning is just an assertion -- the "
        "grader has no evidence you understood the problem. Below, we compare the analysis portions "
        "of your essay against a model answer, with specific ways to strengthen each one.",
        ST["body"]))
    story.append(Spacer(1, 2))

    # Issue 1
    story.append(thin_hr())
    story.append(Paragraph("Issue 1: Landlord's Duty to Mitigate Damages", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "The two-year lease term for a $1,200 monthly payment was created between Carla and the "
        "tenant. Carla will not be entitled to the 12 months of unpaid rent from the tenant because "
        "Carla had the opportunity to re-rent the premises for the equal amount on three different "
        "occasions. Therefore, Carla failed to mitigate her damages, Carla would only be entitled "
        "to a reasonable extent being the weeks to find a new tenant not months.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "When a tenant vacates early, the landlord has a duty to make reasonable efforts to re-let "
        "the premises. Carla had three opportunities to re-rent the house at the same $1,200 "
        "monthly rate but declined each one. Because suitable replacement tenants were available "
        "and Carla took no action to re-let, she failed to exercise reasonable diligence. Her "
        "recoverable damages are limited to the rent lost during the period it would have "
        "reasonably taken to find a new tenant -- likely a matter of weeks, given that three "
        "qualified prospects came to her -- plus any reasonable costs of re-letting.",
        COOL_BG))
    story.append(Paragraph(
        "You reached the right conclusion -- Carla cannot recover all 12 months. But your "
        "analysis skips the key step: <i>why</i> did she fail to mitigate? You said she \"had "
        "the opportunity\" but did not explain what reasonable diligence looks like or why turning "
        "down three qualified tenants falls short of it. The model walks through the standard "
        "(reasonable efforts to re-let), applies the specific facts (three opportunities at equal "
        "rent, all declined), and explains the consequence (damages limited to the reasonable "
        "re-letting period). Each step earns separate points.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> When you write that someone \"failed\" a legal standard, "
        "explain what they should have done and what they actually did. \"Carla should have "
        "re-let the premises, but she turned down three tenants willing to pay the same rent\" "
        "-- that is the analysis."))

    # Issue 2
    story.append(thin_hr())
    story.append(Paragraph("Issue 2: Co-tenant's Right to Share Rental Income", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "Joint tenants with rights of survivorship holding a property are entitled to equal "
        "shares amongst each other to use the property for their own enjoyment and to obtain "
        "payment should property create an income. Here, Alonzo and Barbara are entitled to a "
        "share of the rental income that is payable to Carla under the lease because the tenancy "
        "allows for the holders to receive equal shares of any and all to do with the property.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "When a co-tenant in possession collects rent from a third-party tenant, she must account "
        "to the other co-tenants for their proportionate share of the net rental income. Carla "
        "leased the property to a tenant at $1,200 per month. As one of three equal joint tenants, "
        "Carla must account to Alonzo and Barbara for two-thirds of the net rent collected. Each "
        "co-tenant is entitled to one-third. Carla's right to lease the property as a co-tenant "
        "in possession does not eliminate her obligation to share the proceeds.",
        COOL_BG))
    story.append(Paragraph(
        "You reached the right conclusion but your reasoning is circular: you said they are "
        "entitled to a share \"because the tenancy allows for equal shares.\" That restates the "
        "conclusion as the reason. The model names the specific doctrine -- a co-tenant in "
        "possession who collects third-party rent must <i>account</i> to the others -- then "
        "applies it by calculating shares (one-third each). Graders award points for the specific "
        "rule and the specific math, not for the general principle of equality.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> If your \"because\" clause just restates your conclusion in "
        "different words, it is not analysis. Ask yourself: could a reader who does not know "
        "the law follow my reasoning from the facts to the conclusion? If not, you need to name "
        "the specific doctrine and show the specific calculation."))

    # Issue 3
    story.append(thin_hr())
    story.append(Paragraph("Issue 3: Fair Rental Value and Ouster", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "After Carla moved into the house, she is not required to pay the fair rental value of "
        "$1,500 per month because she occupied the property as Alonzo and Barbara are permitted "
        "to occupy the property. An ouster has not occurred per the facts, therefore, all tenants "
        "are able to occupy the property equally.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "A co-tenant in sole possession generally has no obligation to pay fair rental value "
        "to the other co-tenants, because each co-tenant has an equal right to possess the "
        "entire property. This changes only if an ouster occurs -- meaning the co-tenant in "
        "possession denies the others the right to enter or use the property. Here, the facts "
        "do not indicate that Carla locked Alonzo and Barbara out, refused them access, or "
        "otherwise denied their right to co-occupy. Without an ouster, Carla owes nothing for "
        "her sole possession.",
        COOL_BG))
    story.append(Paragraph(
        "You stated the right conclusion twice -- no ouster, no rent owed -- but never defined "
        "what ouster actually <i>is</i>. The model defines it (denying the other co-tenants the "
        "right to enter or use the property), then walks through the facts to show it did not "
        "happen (no lockout, no refusal of access). Your essay says \"an ouster has not occurred "
        "per the facts\" without explaining which facts you examined or what you were looking for. "
        "A grader reading your version cannot tell if you know the ouster doctrine or just guessed.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> Before saying something did <i>not</i> happen, define what it "
        "would look like if it <i>did</i>. \"Ouster means one co-tenant denies the others access. "
        "Here, nothing suggests Carla prevented Alonzo or Barbara from entering the house.\" Now "
        "the grader knows you understand the doctrine, not just the answer."))

    # Issue 4
    story.append(thin_hr())
    story.append(Paragraph("Issue 4: Whether a Lease Severs a Joint Tenancy", ST["h1"]))
    story.append(Paragraph("Your analysis:", ST["h2"]))
    story.append(shaded(
        "A JTWROS does not sever by leasing a property to a tenant, the ownership interests "
        "remain the same. The only way to sever is by transferring their interest during their "
        "lifetime not in their will after death. The leasing of the property to the tenant did "
        "not sever the relationship between the three children and did not create any effect "
        "following her death.",
        WARM_BG))
    story.append(Paragraph("Model analysis:", ST["h2"]))
    story.append(shaded(
        "The critical question is whether Carla's lease to the tenant severed her joint tenancy "
        "interest. Severance requires the destruction of one of the four unities (time, title, "
        "interest, possession). In the majority of jurisdictions, a lease grants a temporary "
        "possessory interest but does not permanently destroy the unity of interest or title, "
        "so it does not sever the joint tenancy. Some jurisdictions hold that a lease temporarily "
        "disrupts unity of possession, creating a partial severance during the lease term. Under "
        "the majority rule, which this prompt likely tests, the joint tenancy survived. Therefore, "
        "when Carla died, her interest passed by right of survivorship to Alonzo and Barbara "
        "-- her attempted devise to her son in her will had no effect.",
        COOL_BG))
    story.append(Paragraph(
        "This is the most important issue on the prompt, and your analysis did not engage with "
        "the core question. You stated that a lease does not sever -- but this is exactly what the "
        "question is asking you to analyze, not assume. The model explains <i>why</i>: a lease "
        "is a temporary possessory interest that does not destroy the four unities required for a "
        "joint tenancy. It also acknowledges the minority view (some courts find partial "
        "severance), which shows the grader you understand this is a contested area. On the bar "
        "exam, treating a debatable point as settled is the single fastest way to lose points.",
        ST["body"]))
    story.append(action_box(
        "<b>Build this habit:</b> When a question asks \"what effect, if any\" -- that is a "
        "signal that the answer is genuinely debatable. State both sides. \"Under the majority "
        "rule, no severance because... Under the minority rule, possible severance because...\" "
        "Then pick a side and conclude. Showing both views earns more points than asserting one."))

    # Conclusory vs Proper
    story.append(Spacer(1, 4))
    story.append(HRFlowable(width="100%", thickness=0.8, color=GOLD, spaceAfter=4, spaceBefore=6))
    story.append(Paragraph("Conclusory Analysis vs. Proper Analysis", ST["h1"]))
    story.append(Paragraph(
        "Below are specific sentences from your essay rewritten to show the difference. The "
        "conclusory version states the outcome. The rewritten version explains <i>why</i> the "
        "facts lead there.",
        ST["body"]))

    # Rewrite 1
    story.append(Paragraph("<i>Duty to mitigate</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "Carla failed to mitigate her damages, Carla would only be entitled to a reasonable "
        "extent being the weeks to find a new tenant not months.",
        "Carla failed to mitigate because she turned down three tenants willing to pay the same "
        "$1,200 rent. Her recoverable damages are limited to the weeks it would have reasonably "
        "taken to re-let, not the remaining 12 months."
    ))

    # Rewrite 2
    story.append(Paragraph("<i>Co-tenant rental accounting</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "Alonzo and Barbara are entitled to a share of the rental income because the tenancy "
        "allows for the holders to receive equal shares of any and all to do with the property.",
        "Carla collected $1,200 per month from a third-party tenant, so she must account to "
        "Alonzo and Barbara for their share. As equal one-third joint tenants, each is entitled "
        "to $400 per month."
    ))

    # Rewrite 3
    story.append(Paragraph("<i>Ouster</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "An ouster has not occurred per the facts, therefore, all tenants are able to occupy "
        "the property equally and fairly without paying either tenants.",
        "Ouster requires one co-tenant to deny the others access. Nothing suggests Carla locked "
        "Alonzo or Barbara out, so no ouster occurred and Carla owes no fair rental value."
    ))

    # Rewrite 4
    story.append(Paragraph("<i>Severance by lease</i>", ST["h2"]))
    story.extend(rewrite_pair(
        "A JTWROS does not sever by leasing a property to a tenant, the ownership interests "
        "remain the same.",
        "Severance requires destroying one of the four unities. A lease transfers temporary "
        "possession but does not destroy unity of title or interest. Because the joint tenancy "
        "survived, Carla's interest passed to Alonzo and Barbara by survivorship at her death."
    ))

    # Closing
    story.append(HRFlowable(width="100%", thickness=0.4, color=BORDER, spaceAfter=4, spaceBefore=6))
    story.append(Paragraph(
        "You spotted most of the right issues and your instincts are sound -- you generally reach "
        "the correct outcome. The consistent pattern is that you state conclusions without the "
        "reasoning that earns the points: (1) define the standard before applying it; (2) when "
        "you say someone \"failed,\" explain what they should have done; (3) when a question "
        "says \"if any,\" treat it as debatable and show both sides; (4) replace circular "
        "reasoning with specific facts and specific calculations.",
        ST["body"]))
    story.append(Spacer(1, 10))
    story.append(Paragraph("Bar Prep by SHEP  |  May 14, 2026", ST["footer"]))
    doc.build(story)
    return output_path


if __name__ == "__main__":
    p1 = build_business_associations()
    print(f"Business Associations: {p1}")
    p2 = build_real_property()
    print(f"Real Property: {p2}")
