/*
  LetDash navy and acid lime design system (batch 5 layout, colours from batch 7b mock-up F). Plain CSS, no
  build step, dark theme only (color-scheme: dark). Contrast of the token pairs is checked by tests/test_b5_p1.py:
  add new pairs there.
  Every colour, radius, shadow, spacing step and font lives in :root below; nothing else hard-codes a colour.

  Layout
    .shell.with-nav      signed-in layout: sidebar (from 900px) + main
    .sidebar             dark navy nav landmark (#site-nav); slide-over panel on phones (app.js Menu)
    .topbar              phone header: .topbar__brand (LetDash wordmark, batch 15b J4) + .topbar__context
                         (.topbar__sub, .topbar__title) + .menu-btn on the right
    .auth-shell          signed-out pages: centred .auth-card with .brand--auth; .auth-links under a form ("Forgot
                         password?", "Back to sign in", batch 12 E-21)
    .page-head           page heading row (h1 + .page-head__date); --stack for h1 with meta lines below
    .sections            vertical stack of cards

  Components
    .card                navy box with a hairline border; parts .card__head, .card__heading, .card__title, .card__sub,
                         .card__link, .card__body, .card__foot; modifier .card--compact
    .card--tiles         a section that holds a tile grid: no card box, heading + count line straight on the page so
                         the tiles stand out; its .card__body (tenants, tenancy details) stays a card; on the Overview
                         (.prop-card, .landlord-card) the heading row is a slim card
    .prop-card           Overview property card (on .card); --compact; .prop-card__chips holds the compliance chip
                         and the open repair chip (batch 12 E-18, worst first; data-status is the combined colour);
                         the status modifiers (--overdue --gap
                         --due_soon --ok --none) are markers for tests and later styling, with no rules yet
    .tiles / .tile       summary numbers: .tile__num (--legal --good-practice --due-soon --ok), .tile__label
    [data-border]        F-55 status border of a tile or card (2px, --c-border-* tokens): red, orange, gp (blue-grey),
                         green or plain (rental.web.borders; the F-55 block at the end of this file)
    .chip                status pill, text always says the status: --overdue --missing --due-soon --ok
                         --good-practice --none (macro chip(status) in _macros.html; badge() is an alias); --test
                         is the grey "TEST" chip after a test property's address (macro test_chip(prop), batch 7b)
    .btn                 button or link button: --primary (lime, the single main action) --secondary (outline
                         on dark) --danger --dashed (44px min height)
    .rows                list reset with hairlines between rows
    .list-row            one row: .list-row__title (optional small), .list-row__meta (right, mono); used for History,
                         Settings, the property set-up question list and entries marked as a mistake
    .item-tiles          compliance items as tiles (batch 5): li.item-tiles__cell (--files: a past item with its
                         files under the tile, .item-tile__files) holding one a.item-tile with .item-tile__top
                         (.item-tile__icon square + chip), .item-tile__name (3 lines at most), .item-tile__kind,
                         .item-tile__due; top strip (6px) --red --amber --green --grey, solid for legal items and
                         dashed for good practice (--dashed, batch 12 E-2). 2 per row, 3 from 900px. Used on
                         the property page, Overview, checklists, Rules (for you as landlord) and property set-up results
    .section-title       in-page section heading; --caps for the small uppercase label style
    .empty               empty state: optional icon + text
    .date                JetBrains Mono for dates
    .tabs / .tabs__tab   underlined tab bar; current tab has aria-current="page". The property tabs (Summary, Rent,
                         Repairs, MTD, Marketing, Documents, History; batch 10, MTD batch 11a, each with an icon)
                         scroll sideways on phones with no visible scrollbar, and app.js setupTabs keeps the current
                         tab in view. Batch 20 F-33: from 480px they wrap onto more rows (every tab shows); on phones
                         .tabs-wrap holds the nav with a fade and a .tabs-arrow button (--prev, --next) on each edge
                         that has more tabs (.tabs-wrap--more-start / --more-end, set by setupTabs)
    .flash               flash message card: --ok --error --warn (amber, batch 13) --info, with an icon
    .banner              inline notice (.banner.warn)
    .icon                inline SVG from the icon() macro
    .visually-hidden     (alias .sr) hidden text for screen readers
    Forms                label, input, select, textarea at 44px; .hint, .field-error, fieldset, legend,
                         label.check, .stack, .narrow
    Padded card          .card--pad (content straight inside, no head/body parts); .card--accent = navy tint + left
                         accent (correction mode); .card__h small card heading
    Item screen          .entry (+ __head) "Current entry" card; .facts / .facts__item (--wide) label-value grid;
                         .file-list + .file-row tinted file links; .btn-pair two equal buttons
    Disclosures          details (generic card); details.add-entry = dashed full-width "Add a new ..." button
                         with .add-entry__body; details.row-details = a row inside a card (.row-details__meta,
                         .row-details__body)
    .form-actions        submit row: primary bottom-right from 700px, full width on phones; form_actions() macro
                         --wizard (property set-up, batch 12): Back on the left, Skip and the primary on the right
                         from 700px; on phones the primary first, then Skip, then Back (column-reverse)
    .progress            wizard step text (.progress__label) + progress.progress__bar; .wizard-head wraps them
    .crumbs              back link above a page heading
    .tenant-card         tenant details box (tinted); also .agent-card (letting agent on a tenancy card) and
                         .ll-card (Settings > Legal landlords: details, Edit details, .signature-form)
    .signature-preview   signature image on a white panel (dark ink stays visible on the navy theme)
    .banner--info        info card (offline upload queue); .banner.warn amber notice
    .error-card          error page card with alert icon
    .code-input          6-digit code field (JetBrains Mono, letter-spaced); .btn--block full-width button
    .file-picker         "Choose files" button + "n files ready to save" line (JS), plain input without JS;
                         [data-native-picker] for forms the browser posts itself (app.js adds the .chosen-files list)
    .chosen-files        picked files as rows with thumbnail and Remove (built by app.js)
    table.rules          rules catalogue in .rules-card; below 900px each tr is a stacked card using td[data-label]
    .steps, .plain-list, .qr, .small, .meta   small helpers
    .kind-line           "Legal requirement" / "Good practice" line under an item heading
    .tenancy-docs        Tenancy documents card: one .doc-slot (on .card__body) per slot with .doc-slot__title,
                         a .file-list, an empty state, .doc-slot__from (deposit entry files) and
                         details.add-entry--slot (a smaller "Add a file" button); each slot has the id
                         docs-<tenancy id>-<slot key>. Batch 15b J3 (F-14): .on-file is the "Certificate on file" /
                         "Add it in the tenancy documents" line inside Edit tenancy (icon + text, links 44px tall)
                         Batch 21 K1 (F-34): no longer on the Summary tab (Edit tenancy and the Documents tab)
    .attention           Summary tab "Needs attention" card of a.attention-chip links (batch 21 K1, F-34); with
                         .details-tile__docs, details.start-group and details.finance (see the batch 21 K1 block)
    .earlier-versions__list  item screen "Earlier versions" list of .earlier-version (--replaced, --earlier,
                         --deleted), .earlier-version__title, .earlier-version__line; .entry__earlier link
    Documents archive    form.archive-search (+ __row); .archive-section cards of .archive-group (+ __title with
                         small, __link); details.archive-earlier "Earlier (n)"; details.archive-mistakes at the
                         bottom; data-file-name / data-file-group / data-file-section / data-no-match hooks for
                         the app.js filter
    .nav-house           sidebar house icon per property, coloured by its worst status (batch 7c; replaced the
                         round dot): .overdue .gap .due_soon .ok .good_practice_only .off, with .sr status text;
                         .brand is the LetDash logo (batch 15b J4, F-11): .brand__icon tile with the gable-house
                         mark (.logo-mark) + the outlined wordmark (svg.logo, role img, aria-label LetDash; macros in
                         _logo.html). .logo__letters / .logo__a / .logo__door / .logo__knob take their colours from
                         --logo-l, --logo-e, --logo-t (LET as a traffic light, F-59), --logo-letters, --logo-a and --logo-knob (tokens only); --topbar, --sidebar, --auth sizes
    .fact-chips          property header facts (batch 7c): ul of li.fact-chip (neutral, .fact-chip__icon + text),
                         wrapping; gas, licence, appliances, OpenRent and the legal landlord. Batch 9 Z4: the tenure
                         chip (house-key icon) is li.fact-chip--overdue (under 85 years, Lease ended) or
                         --due-soon (under 90 years) when flagged, with the words in its text. Batch 12 E-17: the
                         "EPC D" chip (data-epc) is --ok (meets the minimum), --overdue (below it, or expired) or
                         --due-soon (exempt), its status in hidden words too. Batch 14 F-12: the current
                         tenancy's "Agent: <name>" chip is li.fact-chip--link with a.fact-chip__link (44px tall,
                         building icon) to the agent card (#agent-<tenancy id>)
    .lease-card          Summary tab "Ownership" card (batch 9 Z4, renamed batch 12 E-15): dl.facts with the "Lease"
                         line (tenure, end date, time left, flag chip), the start date and term when given, and the
                         purchase line ([data-purchase], E-15).
                         fieldset.lease-fields on the property form: Tenure radios, then .lease-fields__lease
                         ([data-lease-fields], hidden by app.js unless share of freehold or leasehold) with the
                         end date, start date, term, .lease-guidance and .lease-sources
    .nav-sub             tenancies of the viewed property, nested under it in the sidebar / phone Menu (44px rows,
                         long names wrap); selected one has aria-current="true"; details.nav-earlier "Earlier (n)"
    .card__title--ending "This tenancy, ending <date>" heading (batch 12 E-11): amber text, house-person-leaving icon;
                         --ending-soon red in the last 14 days; --active the lime house-person and white text
    .group-title         (batch 10) h3 group heading in a Summary tab tenancy card: .group-title__icon + text
                         (Tenants, Tenancy details, At Tenancy Start, At Tenancy End)
    .past-banner         past-tenancy heading card (on .card--pad.card--accent); its items are .item-tiles;
                         .tenancy-people tenant cards + "Add another tenant" in a tenancy card
    .building-cover      "The property during this tenancy": a .cover-grid of .cover cards, one per item (--red
                         when a legal item has gaps, else --grey) with .cover__head (icon + kind), .cover__title,
                         .cover__entries (.cover__facts + file list) and .cover__gaps (alert rows, red;
                         .cover__gaps--good-practice grey for good-practice items)
    .rent-history        Rent history list on a tenancy card and the tenancy form (.section-title--caps heading,
                         .rows of .list-row: amount, note and the date it started); fieldset.last-increase holds the
                         optional "Last rent increase" fields on the tenancy edit form; on the Rent tab
                         li.rent-history__fix holds "Entered in error" under a change entered by hand (batch 15 F-16);
                         .rent-history__row--error a change marked "Entered in error", struck through (<s>) with
                         "Entered in error: <reason>" (final review concern 3)
    .details-tile        tenancy details tile (batch 7b S7, a .card__body on the tenancy card): dl.details-tile__grid of
                         .details-tile__row (dt with .details-tile__icon + label, dd value, chip or date), 1 column,
                         2 from 900px; .details-tile__links (Edit tenancy and the Start-of-tenancy checklist; Rent history on past cards) below.
                         .card__action is a button in a .card__head row ("+ Add tenancy", batch 7b S8);
                         .tenant-card__icon (person) + .tenant-card__main, .chip--lead "Lead tenant" (batch 7b S6)
    .rent-card           Rent tab (batch 7c): the rent card (.rent-card__head: title + .rent-reminder line, dl.facts:
                         rent, payment day, tenancy, then the "Propose a rent increase" primary in .rent-card__action)
    .rent-section        Rent tab card holding the notices (.rent-notices) and the Rent history (batch 7c; it was a
                         block on the Summary tab's tenancy card before)
    .rent-reminder       tenancy header line under the card title: --next the batch 9 C1 sentences ("You can propose
                         an increase now. ..." or "You can propose the next increase from <date>. ...", in
                         .rent-reminder__text so they wrap beside the icon), --rises
                         "Rent rises to £X on <date>" with an up arrow (from the day a notice is served, or until a
                         Tribunal decision applies), --challenged "Challenged at the Tribunal: the rent stays at £X
                         until the decision" with the alert icon (batch 15 final review I-2)
    .rent-notices        Section 13 notices in the Rent section (batch 6 Q5): .rent-notice rows with .rent-notice__head
                         (.rent-notice__title + status chip), .rent-notice__facts (what happened), the PDF .file-row
                         (and batch 17 F-25 evidence files, a[data-notice-evidence]) and details.add-entry--slot
                         actions (Mark as served, Agreed a different amount, Withdraw). Batch 15b J3: "Add evidence"
                         per recorded event (details[data-add-evidence], .rent-notice__event names the event) and
                         .rent-notice__reminder (amber "Not served yet" chip + text) on a notice signed by hand (F-19);
                         .rent-card__unsigned is the note under "Propose a rent increase"; .calc__sign the calculator's
                         signature choice; .ll-card__unsigned the Settings text beside the "No signature stored" chip;
                         .notice-created the "Print and sign before you serve" page.
    .calc                rent increase calculator form: .calc__inputs card (left) and aside.calc__summary (right) from
                         1000px, stacked (summary below) on phones; .calc__pair (current rent + frequency),
                         .calc__check (.calc__broken rule list + "Use <date>" button, .calc__ok), .calc__actions,
                         .calc__warn (amber "must be higher than the current rent" note, batch 6 Q4),
                         .calc__label/.calc__date (earliest date in large type), .calc__reason, .calc__note,
                         table.calc__table, ul.calc__guidance; .calc-gaps is the "add these in Settings" banner
    .seg                 read-only segmented display (Per week / Per month): .seg__opt, the current one has
                         aria-current="true", a check icon and the filled style (never colour alone)
    .mortgage-card       property page Mortgage section (batch 15b J1; a grid since batch 19 F-29: .mortgage-question,
                         red .banner.error or amber .banner.warn, table.mortgage-grid, .mortgage-card__add and
                         details.mortgage-card__errors; see the block further down);
                         dd.account holds the masked account number (.account__masked) and details.account-reveal
                         (Show, the full number in .account-reveal__full); app.js swaps it for .account-reveal__btn;
                         .pre-line keeps line breaks in free text. The Overview personal reminder is a tile,
                         li.item-tiles__cell[data-kind="personal"] with the house icon and a chip--due-soon (ending)
    .photo-grid          Marketing tab (batch 7): ul of li.photo-card (--main for the main photo), each with the image
                         (.photo-card__img, 4:3, lazy), .photo-card__body: .photo-card__name ("Main photo" chip +
                         number and file name), form.photo-card__label (label input + Save label) and
                         .photo-card__actions (Move up, Move down, Make main photo, Delete: full-width 44px buttons).
                         2 per row on phones, 3 or 4 from 700px. .photo-upload is the "Add photos" card;
                         .photo-delete the delete confirm page (.photo-delete__img). Batch 7 W2: .photo-card shows a
                         480px thumbnail; .photo-download-all ("Download all", in the Photos heading row);
                         .advert (advert text card: textarea, .advert__count, .advert__actions with Copy and Save);
                         .storage-meter (.storage-meter__text, meter.storage-meter__bar, .storage-meter__warn amber
                         note at 80%)
    .repairs-tab         Repairs tab (batch 9): .repairs-head card (title + "Report an issue" primary in
                         .repairs-head__row, form.repair-filters: Show and Category selects, Filter, .repair-filters__clear),
                         .repair-list cards (.repair-list__title; details.repair-closed folds the closed issues) holding
                         ul.repair-rows of li.repair-row > a.repair-row__link: .repair-row__icon (spanner square),
                         .repair-row__main with .repair-row__title, .repair-row__chips (urgency and status chips,
                         .repair-row__category), .repair-row__targets and .repair-row__meta (last entry date).
                         .tabs__icon is a small icon before a tab label (every tab has one)
    .repair-target       "Respond by <date>: met / missed / pending / not recorded"; --missed adds red text and an alert
                         icon, and the word always says it (never colour alone)
    Repair issue page    .repair-head__icon + .repair-head__chips (urgency, status) under the h1; .repair-facts card
                         (dl.facts, photos, .repair-facts__added); .repair-targets card (dl.facts of targets,
                         details.repair-earlier "Earlier rounds" with .repair-round + __title); .repair-timeline card:
                         ol.repair-entries of li.repair-entry (--correction indented with an accent edge),
                         .repair-entry__head (__type, time, __channel), __link (corrects / corrected later),
                         __note, files, __added (who added it and when); .repair-add card ("Add an entry" form,
                         .repair-add__access hint; [data-show-for] parts follow the type with JS).
                         Batch 14: .repair-head__stage (the status with its one-line meaning, F-6), .repair-add__stage
                         (what to do next, under the Type), .repair-entry__who ("from James Vear", F-5), the shared
                         Who field (select[data-who] + [data-who-name] name box for Someone else) and
                         .repair-split (open issues split: in progress / awaiting tenant confirmation).
                         .repair-form is "Report an issue"; .repair-settings is Settings > Repair targets
    Repair alerts        (batch 9 Z3) .repair-tile: the Summary tab "Open repairs" section, one item tile (strip red when
                         a target is missed, amber when due within 2 days, grey otherwise; the chip says it) with
                         ul.repair-alerts under it (in .item-tile__files): a.repair-alert per issue (--missed: red text
                         and an alert icon), .repair-alert__title and small target lines. .tile--wide spans the
                         Overview .tiles row; .repair-overview is the Overview "Repairs" tile (.repair-overview__head
                         icon + name, __counts number + "open" + __missed red line with alert icon, ul __list of
                         property links: __address, __line). .repair-guide is the folded "Target times and the law"
                         panel on the Repairs tab (.repair-guide__icon, __sources). .repair-head__record holds the
                         "Download repair record (PDF)" button on the issue page
    .messages-tab        Messages tab (batch 16, L18): .messages-head card (title + "Add message" primary in
                         .messages-head__row, the .tab-intro, __past read-only banner, form.message-filters: Direction,
                         Channel, Tenant selects, From and To dates, search box, __buttons with Apply, __note) folded in
                         details.message-filters-box ("Filter messages", F-76) inside .message-filters-bar, with
                         .message-filters__active ("Filtered: ..." and the __clear link) after it; .message-list card (__title, __count, __more "Show more") holding
                         ol.message-rows of li.message-row (stacked cards, nothing scrolls sideways at 360px;
                         --correction indented with an accent edge): __head (__icon speech bubble, __dir, __channel,
                         time), __subject, __people (tenant and landlord side), __link (corrects, corrected later,
                         repair), __summary, files, __added, __actions (Edit and Delete, F-76); --entry (F-45) is a pet request
                         or repair entry, read only, with .chip--entry, the __link back and __note ("Correct it
                         there") in place of __actions. The same row shows in a
                         repair issue's timeline (F-71: no "Add message about this issue").
                         .message-form is Add message / Edit message (.message-form__corrects banner);
                         .message-earlier holds the deleted messages (Earlier versions, Restore; F-76).
    .tab-intro           F-76: a tab's intro paragraphs (rental.web.intros, the tab_intro macro), in the tab's head
                         card
    .tab-head            F-105: the head card of Ask TInA, Rent, End tenancy, Register, Timeline, Marketing,
                         Documents and Change log (the tab_head macro): h2 with the tab icon, .tab-head__status
                         (--ending, --ending-soon; __status-icon) on Timeline and End tenancy, then the .tab-intro
    .pets-tab            Pets tab (batch 17, L16): reuses the Repairs tab parts (.repairs-head, .repair-guide,
                         .repair-list, .repair-rows, li.repair-row.pet-row); .pet-deadline is the decision deadline in
                         words (--amber with 7 days or fewer left, --red once passed; neutral otherwise). The request
                         page reuses the repair issue page parts (.repair-facts, .repair-timeline, .repair-add) with
                         .pet-entry__details and .pet-decision; .pet-tile is the Summary tile (as .repair-tile),
                         .pets-granted the "Pets at this property" card, .pet-overview the Overview tile (as
                         .repair-overview); .pet-form is Log a pet request (F-71: no message banner); .pet-caution is
                         the "WhatsApp or text" caution under a channel (shown without JS; app.js shows it only while
                         that channel is chosen)
    .timeline-tab        Timeline tab (batch 18, L21): the .tab-head card (F-105; status line with the E-11 ending colours,
                         .tl-chips filter and zoom links, a.tl-chip with aria-current="true" and a check icon on the
                         current one); .tl-line card holding svg.tl-svg (.tl-axis solid up to today, --future dashed
                         after it, .tl-tick + __label, .tl-today lime line + __label, .tl-stem and .tl-dot per marker,
                         a.tl-marker (--ok --accent --due-soon --overdue --neutral, --upcoming dashed and faded) with
                         __tap, __ring (focus), __frame, the icon, __count bubble and __date label); .tl-panel details
                         cards (shown by :target); .tl-list card of ol.tl-rows: li.tl-row (__icon square, __meta date,
                         kind and Upcoming chip, __title link, __detail, ul.tl-notes corrections, .tl-files,
                         details.tl-children entries and messages) and li.tl-today-row divider. Phones: the line and
                         panels hide and the rows become dated cards on a vertical line, by the tab's own width (@container timeline,
                         below 900px: the markers stay at least 44px wherever the line shows); the __count bubble is lime --tl-colour carries a state
                         colour (status strip tokens only)
    .mtd-tab             MTD tab (batch 11a M3): .mtd-head card (title + .mtd-head__actions: "Add expense" primary and
                         "Add income"; form.mtd-period: Tax year, Quarter and Type selects + Show; .mtd-head__period line
                         with the update deadline); .mtd-cards grid of 4 .tile.mtd-card (.mtd-card__label, __num with
                         --income --expense --finance --net, __sub, __ytd year to date); .mtd-note (repayment mortgage
                         note); .mtd-cats "By HMRC category" card (ul.mtd-cats__list of .mtd-cats__row: __name with
                         small __field, one or two __value columns, --two when the year to date is shown, --head,
                         --total, --finance); .mtd-list card of ul.mtd-rows > li.mtd-row > a.mtd-row__link (__date,
                         __main with __category and __desc, __end with __amount, the status chip and __receipt icon)
    MTD forms            .mtd-form card (add or edit an expense or income entry: __status chip line, __fixed category of
                         a mortgage entry, __note improvements banner, __facts); .mtd-examples (+ __item [data-example-for]
                         hidden by app.js unless chosen, __name); .mtd-danger delete / not received card.
                         .archive-receipt__link is "Open the expense" under a receipt on the Documents tab
    .mtd-page            MTD menu page per taxpayer (batch 11a M4; also .mtd-tab, reusing its .mtd-head, .mtd-cards,
                         .mtd-cats): .mtd-page__title h1 with the receipt icon; .mtd-period--taxpayer adds the Taxpayer
                         select; .mtd-cards--five adds the .mtd-card--deadline card (__num--deadline); .mtd-card__other
                         is the other property income line on the Rent income card; .mtd-props "By property" card with
                         .mtd-table-box (scrolls sideways inside the card on a phone) holding table.mtd-table.
                         .mtd-head__taxpayer is the MTD taxpayer line on the MTD tab. .nav-icon is the receipt icon of
                         the MTD menu item. .mtd-taxpayer-field / .mtd-taxpayer-warning: the MTD taxpayer select and
                         its warning on Edit property details; .mtd-taxpayer is a taxpayer in Settings
                         Batch 13 N1: .mtd-shared "All properties (shared costs)" list card (reuses .mtd-list and
                         .mtd-rows; __hint); .mtd-row__shared the split / share line of a row; .mtd-form__shared the
                         note on the shared expense form; .mtd-submit "Quarterly updates" card (ul.mtd-submit__list of
                         .mtd-submit__row: __status chip and text, form.mtd-submit__form date + button);
                         .mtd-changes "Changes since your last submission" card (table.mtd-changes__table in a
                         .mtd-table-box, left aligned text).
                         Batch 13 N2: .mtd-sent the figures sent panel under an update's status (__title with the
                         "Recorded on" line, __summary, table.mtd-sent__table: __row--total, __row--differs amber text
                         with the word "Differs" in __word; __actions "Record figures sent" + __mark link);
                         .mtd-sent-choose the update select and .mtd-sent-form__app the "App now" hint under each box
                         on the Record figures sent screen. .mtd-sent__blank is the "N boxes left blank (not
                         recorded)" line and .mtd-sent__none the
                         "Not recorded" word in the Sent column (N2 review n2).
                         Batch 13 N3: .mtd-entries "All entries" list card (reuses .mtd-list and .mtd-rows: every row a
                         stacked card, nothing scrolls sideways at 360px; .mtd-row__property the property line);
                         __tools holds form.__filters (Property, Period, Type, Status selects, search box, __buttons
                         with Filter and the __clear link) and __add (two form.__add-form: "Expense for" or "Income
                         for" select + button); __count line; __more "Show more" button.
                         .mtd-overview is the Overview "MTD this quarter" tile (a.tile.tile--wide: __head icon + name,
                         __period, __figures of three __fig (label + __num), __due deadline or submitted line).
                         Batch 15 H2 (F-15): the tile is now div.tile.tile--wide.mtd-overview (it holds forms) with
                         a.mtd-overview__link around the head and figures; --soon amber border and __due--soon line
                         with the "Due soon" chip; --overdue red border. .mtd-overdue is a red line of an update past
                         its deadline (__line chip + text); .mtd-actions holds "Mark as
                         submitted" (form.mtd-submit__form) and details.mtd-actions__not-sent "It was not sent";
                         .mtd-late is the MTD page card of those lines; .mtd-card--soon the amber Next deadline card
                         (.mtd-card__chip).
                         Batch 15b J3 (F-23): the Overview tile holds no forms; .mtd-overview__open is its "Open MTD to
                         mark it submitted" link (a secondary button). .mtd-actions is on the MTD page only.
                         Batch 15b J2 (F-9): .cgt-overview is the Overview "Capital Gains Tax" tile (a .repair-overview
                         list, --soon amber or --overdue red border); .sale-card is the property's "Selling or stopped
                         letting" card (.sale-card__cgt reminder box with --soon / --overdue border, __costs list,
                         __done form) with .sale-guidance (details with the gov.uk quotes).
    .end-tab             End tenancy tab (batch 20, L22): the .tab-head card (F-105; status as E-11, .end-head__left "n days
                         left" or .end-head__past, and the .end-head__note "not legal advice" line); .end-routes holds .route-cards (one
                         column, two from 700px) of article.route-card (.route-card__title with .route-card__icon,
                         text, .route-card__action secondary button or .route-card__soon); .end-route "How it is
                         ending" (dl.facts, .end-route__files, check lines, details.end-route__withdrawn);
                         .end-checklist the At Tenancy End tiles (card--tiles) with Correct end date; .end-close
                         the Close the tenancy form (the one primary button).
    .check-lines         check lines (batch 20, macro check_lines): li.check-line (--met --not_met --check_yourself
                         --not_yet_required --not_required_override --not_needed) with the .check-line__state chip
                         (icon + words: Met, Not met, Check yourself ...; the status chip colours, never colour
                         alone), .check-line__main (__label, __evidence, __links: Fix this, Source and
                         .check-line__verified "verified on <date>", each link 44px tall).
    .possession          the Landlord initiated route (batch 20 E2, possession.html): .ground-choice (a ground's
                         tickbox with .ground-choice__meta), details.ground-other with .ground-other__row (another
                         ground and its pasted wording), .court-reasons (the earliest date's reasoning),
                         .possession-ready (Ready / Not ready yet chip and what is still needed); check lines take
                         .check-line__tick (the landlord's own tick, 44px).
    .notice-form         the Tenant initiated form (batch 20): .notice-form__note, .notice-form__shorter (the shorter
                         period's fields, [data-shorter-fields], hidden by app.js while unticked) and
                         .notice-form__checks (the live check lines, aria-live).
    .possession-notice   a Section 8 notice on the End tenancy tab (batch 20 E3): __head (title and the status chip in
                         words), __events (what happened), __actions (secondary buttons), __evidence and __checks
                         (details); .possession-next ("What happens next"), .possession-earlier (earlier notices),
                         .possession-create (Create Form 3A), .possession-cover (the cover sheet), .possession-step.
    .mortgage-grid__balance  batch 20 E3 (F-32): the balance as a small muted line under a mortgage row.
    .house               Overview house picture per property (batch 12 E-20, canvas board K; macro house() in
                         _house.html, view from rental/web/house.py): .house__main (the picture, then
                         .house-panel--tenancy beside it from 600px, below it on phones), .house__picture stacks
                         two SVGs on one viewBox: svg.house__drawing (role="img" with the summary; .house__outline,
                         .house__stairs, .house__door, .house__room labels) and svg.house__badges (a.house-badge per
                         item, the spanner, the dog). a.house-badge--ok --due-soon --overdue --good-practice (dashed)
                         --not-in-force (dotted) set the colour (currentColor); .pulse (red) pulses, never under
                         prefers-reduced-motion; inside the SVG: __tap (72-unit tap area), __box (__ring focus ring,
                         __frame, glyph, __count bubble); in the panels a.house-badge is a 44px HTML square.
                         .house-panel (__title, __list, __empty), --other for property items without a room;
                         ul.house-key (once per page, __swatch--<state>); .house-attention "Needs attention:" and
                         .house-all-ok "All items OK" lines. Batch 23 S1: the key is in each card's issues fold;
                         .house-tip is a badge's hover and focus label (F-51)
    Overview list        batch 23 S1 (F-47, F-48): .prop-list-head, .prop-list, details.prop-issues with
                         summary.prop-issues__toggle, .overview-wide (Coming up; Repairs and Pet requests,
                         F-100), .overview-register and .landlord-register (F-91) and .coming-up
                         (see the batch 23 S1 blocks at the end)
    .rent-account        Rent tab (L25 S1, board AC1): the Rent account card (#rent-account): __head (title and the
                         __since line), __balance (--due-soon amber text; --overdue and --plain white), __ground8
                         line (a red chip once the Ground 8 level is reached), ul.__problems of li.__problem (__day,
                         __labels chips and the 44px __open link), the folded details.__all "All rent days"
                         (table.rules.__table: stacked rows on phones) and __note.
    .s8-arrears          Section 8 page (L25 S2, board AC4): __note the orange-edged difference note and Universal
                         Credit warning, __hint the blue-grey Ground 11 hint (good practice style, never red);
                         .section8-guide__tenancy the "This tenancy" box in the "Section 8 and the law" panel.
*/

@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Plus Jakarta Sans"; font-style: normal; font-weight: 800; font-display: swap;
  src: url("fonts/plus-jakarta-sans-latin-800-normal.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2"); }

:root {
  /* dark theme only: native date pickers, selects and scrollbars render dark */
  color-scheme: dark;
  /* page: solid navy (batch 7b S9, mock-up F) */
  --c-ground: #131936;
  /* sidebar and phone header; the selected item has the --c-nav-active fill and a lime left bar (--c-nav-current) */
  --c-nav-bg: #0C1027;
  --c-nav-active: #1F2850;
  --c-nav-text: #EEF1F8;
  --c-nav-muted: #9AA3C2;
  --c-nav-soft: #C6CCE0;
  --c-nav-add: #BBDF32;
  --c-nav-border: #2B3566;
  --c-nav-sub: #A9B1C9;
  --c-nav-current: #BBDF32;
  --c-on-dark: #FFFFFF;
  /* cards and text */
  --c-card: #1B2347;
  --c-card-border: #2B3566;
  --c-heading: #FFFFFF;
  --c-text: #EEF1F8;
  --c-text-2: #A9B1C9;
  --c-tile-label: #A9B1C9;
  /* accent: icons, links and the selected menu bar, acid lime (icon squares use --c-accent on --c-accent-bg) */
  --c-accent: #BBDF32;
  --c-accent-bg: #26305C;
  --c-link: #BBDF32;
  --c-link-hover: #FFFFFF;
  /* primary button: acid lime with navy text, used for the single main action on a screen */
  --c-primary: #BBDF32;
  --c-primary-hover: #CBEA5A;
  --c-on-primary: #131936;
  /* hairlines, tints and form controls */
  --c-line: #2B3566;
  --c-line-soft: #232C55;
  --c-tint: #222B52;
  --c-field-bg: #141B3A;
  --c-field-border: #6F7AA8;
  --c-dashed: #6F7AA8;
  /* batch 12 E-20: the Overview house picture's outline (the mock-up's line colour; decorative, the badges carry
     the status) */
  --c-house-line: #3A4677;
  --c-danger-border: #F01C1C;
  /* status chips (background / text); OK is traffic-light green #22C55E (F-59, board Z), a solid chip with navy text like the orange one, and never the lime accent (lime is for buttons and links only). Batch 22 F-49
     (board W): red and amber chips are solid, red #E0141E with white text, orange #FF8C1A with navy text. --c-overdue
     is the red for lines, borders and icons only: small text never sits in red straight on navy (it is white, or on
     the solid chip). --c-soon is the orange for lines, icons and text (it reads at 4.5:1 on navy). */
  --c-overdue-bg: #E0141E;
  --c-on-overdue: #FFFFFF;
  --c-overdue: #F01C1C;
  --c-soon-bg: #FF8C1A;
  --c-on-soon: #131936;
  --c-soon: #FF8C1A;
  --c-ok-bg: #22C55E;
  --c-on-ok: #131936;
  --c-ok: #22C55E;
  --c-neutral-bg: #262F57;
  --c-neutral: #B9C1DD;
  /* status strips (top edge of item tiles); not in force and good practice that is overdue or missing use grey
     (anything OK is green, batch 10 final; due soon is amber for both kinds, batch 12 E-1). The grey is a little lighter than mock-up F's #5C6696 so it reaches 3:1 on a card. */
  --c-strip-red: #F01C1C;
  --c-strip-amber: #FF8C1A;
  --c-strip-green: #22C55E;
  --c-strip-grey: #626D9F;
  /* F-55 (boards X, X2): status borders of tiles and cards, 2px (--border-status): red overdue or missing, orange due
     soon, blue-grey good practice outstanding, green OK or positive, plain = the card hairline colour. Lime is never a
     status border. */
  --c-border-red: #F01C1C;
  --c-border-orange: #FF8C1A;
  --c-border-gp: #9AA6D6;
  --c-border-green: #22C55E;
  --c-border-plain: #2B3566;
  --border-status: 2px;
  /* F-45 (board AA): the left edge of a pet request or repair entry shown on the Messages tab (blue-grey, as the
     good-practice border) */
  --c-entry-edge: var(--c-border-gp);
  /* tile numbers (on a card) */
  --c-num-legal: #FF3B30;
  --c-num-good-practice: #B9C1DD;
  --c-num-due-soon: #FF8C1A;
  --c-num-ok: #22C55E;
  /* sidebar status dots (on the dark sidebar) */
  --c-dot-bad: #F01C1C;
  --c-dot-soon: #FF8C1A;
  --c-dot-ok: #22C55E;
  --c-dot-off: #8E97B8;
  /* QR code on the enrol page keeps a light background so phones can scan it */
  --c-qr-bg: #FFFFFF;
  /* focus rings: acid lime everywhere */
  --c-focus: #BBDF32;
  --c-focus-on-dark: #BBDF32;
  /* overlays and shadows */
  --c-scrim: rgba(5, 8, 20, 0.6);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-raised: 0 4px 14px rgba(0, 0, 0, 0.35);
  --shadow-panel: 0 0 24px rgba(0, 0, 0, 0.5);
  /* radius */
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 12px;
  --radius-xl: 14px;
  --radius-pill: 999px;
  /* spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  /* type */
  --font-sans: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Consolas, monospace;
  /* sizes */
  --tap: 44px;
  --sidebar-w: 248px;
  --content-max: 1100px;
}

/* Base */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; min-height: 100vh; font: 16px/1.5 var(--font-sans); color: var(--c-text); background-color: var(--c-ground); }
a { color: var(--c-link); }
a:hover { color: var(--c-link-hover); }
h1 { font-size: 1.6rem; line-height: 1.25; font-weight: 700; color: var(--c-heading); margin: 0 0 var(--space-4); overflow-wrap: anywhere; }
h2 { font-size: 1.15rem; line-height: 1.3; font-weight: 700; color: var(--c-heading); margin: var(--space-6) 0 var(--space-2); }
p { margin: var(--space-2) 0; }
img { max-width: 100%; }
code, .date, time { font-family: var(--font-mono); }
.visually-hidden, .sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.icon { flex: none; vertical-align: middle; }

/* Focus ring: acid lime everywhere (cards, page, sidebar and header) */
:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.sidebar :focus-visible, .topbar :focus-visible { outline-color: var(--c-focus-on-dark); }

/* Shell */
main { width: 100%; max-width: var(--content-max); padding: var(--space-4); }
main > :first-child { margin-top: 0; }
.shell.with-nav main { display: flex; flex-direction: column; gap: var(--space-4); }
.shell.with-nav main > * { margin-top: 0; margin-bottom: 0; }
.topbar { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4);
  background: var(--c-nav-bg); color: var(--c-on-dark); }
.topbar__context { display: flex; flex-direction: column; flex: 1; min-width: 0; }
/* Batch 15b J4 (F-11): the LetDash wordmark, top left of the phone header (a 44px tall link to the Overview) */
.topbar__brand { display: inline-flex; align-items: center; flex: none; min-height: var(--tap); text-decoration: none; }
.topbar__sub { font-size: 0.75rem; color: var(--c-nav-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar__title { font-weight: 700; font-size: 1.06rem; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); flex: none;
  min-width: var(--tap); min-height: var(--tap); padding: 0 var(--space-3); border: 1px solid var(--c-nav-border);
  border-radius: var(--radius-md); background: transparent; color: var(--c-on-dark); font: inherit; font-weight: 600;
  text-decoration: none; cursor: pointer; }
.menu-btn:hover { color: var(--c-on-dark); background: var(--c-nav-active); }
.menu-btn[hidden] { display: none; }

/* Sidebar: slide-over panel on phones, fixed column from 900px */
.sidebar { position: fixed; top: 0; bottom: 0; left: 0; z-index: 30; width: min(300px, 85vw); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-5) var(--space-4) var(--space-6);
  background: var(--c-nav-bg); color: var(--c-nav-text);
  transform: translateX(-100%); visibility: hidden; transition: transform 0.2s ease, visibility 0s linear 0.2s; }
/* Opening: visible at once (no visibility delay) so app.js can move focus to Close menu straight away. */
.sidebar.open, .sidebar:target { transform: none; visibility: visible; box-shadow: var(--shadow-panel);
  transition: transform 0.2s ease, visibility 0s; }
.sidebar__top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: 0 0 var(--space-4); }
.sidebar__spacer { flex-grow: 1; min-height: var(--space-4); }
.brand { display: inline-flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 0 var(--space-2);
  font-weight: 800; font-size: 1.06rem; letter-spacing: 0.2px; color: var(--c-nav-text); text-decoration: none; }
.brand .icon { color: var(--c-accent); }
.brand__icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 36px; height: 36px;
  border: 1px solid var(--c-nav-border); border-radius: var(--radius-md); background: var(--c-nav-bg); }
/* The LetDash logo (inline SVG from _logo.html): white letters and a white gable-house A (F-64), its door knob in navy */
.logo, .logo-mark { display: block; flex: none; overflow: visible; --logo-letters: var(--c-on-dark);
  --logo-l: var(--c-strip-red); --logo-e: var(--c-strip-amber); --logo-t: var(--c-ok); --logo-a: var(--c-on-dark); --logo-knob: var(--c-nav-bg); }
.logo { width: auto; height: 18px; aspect-ratio: 4711 / 773; }
.logo-mark { width: 22px; height: 22px; }
.logo__letters { fill: var(--logo-letters); }
.logo__l { fill: var(--logo-l); }
.logo__e { fill: var(--logo-e); }
.logo__t { fill: var(--logo-t); }
.logo__a { stroke: var(--logo-a); }
.logo__door { fill: var(--logo-a); stroke: none; }
.logo__knob { fill: var(--logo-knob); }
.logo--topbar { height: 16px; }
.logo--auth { height: 24px; }
.sidebar .brand:hover { color: var(--c-on-dark); }
.menu-close { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap); padding: 0 var(--space-2);
  border-radius: var(--radius-sm); color: var(--c-nav-soft); text-decoration: none; font-size: 0.9rem; font-weight: 600; }
.menu-close:hover { color: var(--c-on-dark); background: var(--c-nav-active); }
.scrim { position: fixed; inset: 0; z-index: 20; background: var(--c-scrim); }
.scrim[hidden] { display: none; }
.nav-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.nav-list a, .nav-list button.link { display: flex; align-items: center; gap: 10px; width: 100%; min-height: var(--tap);
  padding: 0 var(--space-3); border: 0; border-radius: var(--radius-sm); background: none; color: var(--c-nav-text);
  font: inherit; text-align: left; justify-content: flex-start; text-decoration: none; overflow-wrap: anywhere; cursor: pointer; }
.nav-list a:hover, .nav-list button.link:hover { background: var(--c-nav-active); color: var(--c-on-dark); }
.nav-list a[aria-current="page"] { background: var(--c-nav-active); color: var(--c-on-dark); font-weight: 600;
  box-shadow: inset 3px 0 0 var(--c-nav-current); }  /* lime left bar (mock-up F), never a lime fill */
.nav-list a.nav-add { color: var(--c-nav-add); }
.nav-list--footer a, .nav-list--footer button.link { color: var(--c-nav-soft); }
.nav-list form { margin: 0; }
.nav-head { margin: var(--space-4) 0 var(--space-1); padding: 0 var(--space-3); font-size: 0.7rem; font-weight: 600;
  letter-spacing: 1.2px; text-transform: uppercase; color: var(--c-nav-muted); }
.nav-note { padding: var(--space-2) var(--space-3); color: var(--c-nav-muted); }
/* Batch 7c: each property's house icon is coloured by its worst status (the sr text says which, never colour alone) */
.nav-house { flex: none; display: inline-flex; color: var(--c-dot-off); }
/* A solid house in the status colour, with a heavier outline: at least as strong as the old 9px dot (Y1 review). */
.nav-house svg { fill: currentColor; stroke-width: 2.4; }
.nav-house.overdue, .nav-house.gap { color: var(--c-dot-bad); }
.nav-house.due_soon { color: var(--c-dot-soon); }
.nav-house.ok { color: var(--c-dot-ok); }
.nav-house.good_practice_only { color: var(--c-dot-off); }  /* grey, same as no items; the sr text says which */

/* Signed-out pages */
.auth-shell { min-height: 100vh; display: flex; align-items: flex-start; justify-content: center; padding: var(--space-6) var(--space-4); }
.auth-card { max-width: 440px; padding: var(--space-6); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-raised); }
.brand--auth { margin: 0 0 var(--space-4); padding: 0; color: var(--c-heading); }
.brand--auth .brand__icon { width: 44px; height: 44px; }
.brand--auth .logo-mark { width: 28px; height: 28px; }
.brand--auth .icon { color: var(--c-accent); }
/* Batch 12 E-21: "Forgot password?" and the other links under a signed-out form, 44px tall tap targets */
.auth-links { display: flex; flex-wrap: wrap; gap: var(--space-4); margin: var(--space-4) 0 0; }
.auth-links a { display: inline-flex; align-items: center; min-height: var(--tap); }

/* Page heading */
.page-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.page-head h1 { margin: 0; }
.page-head__date { font-family: var(--font-sans); font-size: 0.875rem; color: var(--c-text-2); }
.page-head--stack { display: block; }
.page-head--stack h1 { margin-bottom: var(--space-2); }
/* F-99: the property header is a card panel bordered by the Overview card's status colour (F-55 tokens). */
.card.prop-panel { margin-bottom: var(--space-4); overflow: visible; }
/* Batch 7c: property facts under the address as neutral icon chips (not status colours); they wrap on phones */
.fact-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.fact-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 12px;
  border-radius: var(--radius-pill); background: var(--c-neutral-bg); color: var(--c-neutral); font-size: 0.8125rem;
  font-weight: 600; line-height: 1.5; overflow-wrap: anywhere; }
.fact-chip__icon { display: inline-flex; flex: none; }
.fact-chip .chip { margin-left: var(--space-1); }
/* Batch 9 Z4: the tenure chip. Red (under 85 years, Lease ended) and amber (under 90 years) use the status chip
   colours; the chip text always says it in words too. */
.fact-chip--overdue { background: var(--c-overdue-bg); color: var(--c-on-overdue); }
/* Batch 22 F-49: amber information tags (tenure under 90 years, EPC exempt) are the neutral chip with an orange
   outline and orange text */
.fact-chip--due-soon { background: var(--c-neutral-bg); color: var(--c-soon); box-shadow: inset 0 0 0 1.5px var(--c-soon); }
/* Batch 12 E-17: the "EPC D" chip when the rating meets the minimum (red below it, amber while exempt) */
.fact-chip--ok { background: var(--c-ok-bg); color: var(--c-on-ok); }
/* Batch 14 F-12: the "Agent: <name>" chip links to the agent's details; the whole chip is a 44px tap target */
.fact-chip--link { padding: 0; }
.fact-chip__link { display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 0 12px;
  border-radius: inherit; color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.lease-card .chip { margin-left: var(--space-1); }
.lease-fields__lease { padding-top: var(--space-2); border-top: 1px solid var(--c-line-soft); }
.prop-head { margin: 0; font-weight: 700; }
.prop-head a { text-decoration: none; }
.section-title { margin: var(--space-6) 0 var(--space-3); font-size: 1.15rem; font-weight: 700; }
.section-title--caps { font-size: 0.7rem; font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: var(--c-text-2); }
.meta, .crumbs, .small, .progress { color: var(--c-text-2); font-size: 0.9rem; }
.meta { margin: var(--space-1) 0; }
.kind-line { margin: calc(-1 * var(--space-3)) 0 var(--space-4); color: var(--c-text-2); font-size: 0.9rem; font-weight: 600; }
.sections { display: flex; flex-direction: column; gap: var(--space-4); }

/* Card */
.card { background: var(--c-card); border: 1px solid var(--c-card-border); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card); overflow: hidden; color: var(--c-text); }
.card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--c-line); }
.card__heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.card__title { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; font-size: 1.125rem;
  font-weight: 700; line-height: 1.35; color: var(--c-heading); text-decoration: none; overflow-wrap: anywhere; }
.card__title a { display: inline-flex; align-items: center; min-height: var(--tap); color: inherit; text-decoration: none; }
a.card__title:hover, .card__title a:hover { color: var(--c-link-hover); text-decoration: underline; }
.card__title .icon { color: var(--c-accent); }
/* Batch 12 E-11: the current tenancy's heading when it is ending (an end date is set): amber, red in the last 14 days.
   The icon also changes shape (house-person-leaving) and the words say "ending <date>", so not colour alone. */
.card__title-icon { display: inline-flex; }
.card__title--ending { color: var(--c-soon); }
.card__title--ending .icon { color: var(--c-strip-amber); }
.card__title--ending-soon { color: var(--c-heading); }
.card__title--ending-soon .icon { color: var(--c-strip-red); }
.card__sub { font-size: 0.8125rem; color: var(--c-text-2); }
.card__link { flex: none; display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 600; font-size: 0.9rem; }
.card__body { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--c-line-soft); }
.card__body > :first-child { margin-top: 0; }
.card__body > :last-child { margin-bottom: 0; }
.card__foot { padding: var(--space-3) var(--space-5); border-top: 1px solid var(--c-line-soft); }
.card__foot:first-child, .card__head + .card__foot { border-top: 0; }
.card--compact .card__head, .prop-card--compact .card__head { border-bottom: 0; }
/* Batch 12 E-18: the compliance chip and the open repair chip, worst first, wrapping on phones */
.prop-card__chips { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); }
.card .chip { flex: none; }
/* Sections holding a tile grid: no card box, so the tiles (card colour) stand out on the page */
.card--tiles { background: none; border: 0; border-radius: 0; box-shadow: none; overflow: visible; }
.card--tiles > .card__head { padding: 0 0 var(--space-3); border-bottom: 0; }
.card--tiles > .card__body { margin-bottom: var(--space-3); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
.card--tiles > .item-tiles, .card--tiles > .cover-grid { padding: 0; }
.card--tiles > .empty { padding: var(--space-3) 0; }
.card--tiles > .card__foot { padding: var(--space-3) 0 0; border-top: 0; }
.sections > .card--tiles:not(:first-child) { margin-top: var(--space-2); }
/* Overview: the property heading row stays a slim card above its tiles */
.prop-card.card--tiles > .card__head, .landlord-card.card--tiles > .card__head { margin-bottom: var(--space-3);
  padding: var(--space-3) var(--space-4); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }

/* Tiles */
.tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.tile { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-4) var(--space-5);
  background: var(--c-card); border: 1px solid var(--c-card-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
  color: var(--c-text); text-decoration: none; }
a.tile:hover { color: var(--c-text); border-color: var(--c-accent); box-shadow: var(--shadow-raised); }
.tile__num { font-size: 2.125rem; font-weight: 800; line-height: 1.1; }
.tile__num--legal { color: var(--c-num-legal); }
.tile__num--good-practice { color: var(--c-num-good-practice); }
.tile__num--due-soon { color: var(--c-num-due-soon); }
.tile__num--ok { color: var(--c-num-ok); }
.tile__label { font-size: 0.875rem; color: var(--c-tile-label); }
.tile__extra { font-size: 0.8125rem; color: var(--c-text-2); }

/* Chips */
.chip { display: inline-block; padding: 3px 10px; border-radius: var(--radius-pill); font-size: 0.75rem;
  font-weight: 700; line-height: 1.5; white-space: nowrap; vertical-align: middle; }
.chip--overdue, .chip--missing { background: var(--c-overdue-bg); color: var(--c-on-overdue); }
.chip--due-soon { background: var(--c-soon-bg); color: var(--c-on-soon); }
.chip--ok { background: var(--c-ok-bg); color: var(--c-on-ok); }
.chip--good-practice, .chip--none { background: var(--c-neutral-bg); color: var(--c-neutral); }
.rule__recheck { display: block; margin-top: 0.25rem; }
/* Test property (batch 7b): grey, after the address; the text "TEST" says it, the colour only repeats it */
.chip--test { flex: none; margin-left: var(--space-2); background: var(--c-neutral-bg); color: var(--c-neutral);
  font-family: var(--font-mono); letter-spacing: 0.5px; vertical-align: middle; }
h1 .chip--test { font-size: 0.8125rem; }
.test-delete .actions { margin-bottom: 0; }

/* Rows */
.rows { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.rows > li { border-bottom: 1px solid var(--c-line-soft); }
.rows > li:last-child { border-bottom: 0; }
.list-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3);
  min-height: var(--tap); padding: var(--space-3) var(--space-5); color: var(--c-text); text-decoration: none; }
a.list-row:hover { background: var(--c-tint); color: var(--c-text); }
/* Rows and tabs run to the card edge, where overflow would clip an outside ring: draw it inside. */
.list-row:focus-visible, .list-row a:focus-visible { outline-offset: -2px; }
.list-row__title { flex: 1 1 12rem; min-width: 0; overflow-wrap: anywhere; }
.list-row__title small { display: block; font-size: 0.8125rem; color: var(--c-text-2); }
.list-row__meta { flex: 0 1 auto; margin-left: auto; font-size: 0.75rem; color: var(--c-text-2); text-align: right; }
.list-row > .icon { color: var(--c-accent); }
/* Rent history (batch 6 Q2): a compact list inside a tenancy card or the tenancy form. */
.rent-history .section-title { margin: var(--space-4) 0 var(--space-1); }
.rent-history .list-row { padding-left: 0; padding-right: 0; }
/* Batch 15 F-16: "Entered in error" under a rent change entered by hand (Rent tab only). A change marked so stays
   listed, struck through, its reason below (the words say it, not only the line). */
.rent-history__fix { list-style: none; padding: 0 0 var(--space-2); }
.rent-history__row--error s { color: var(--c-text-2); }

/* Item tiles: the whole tile is one link; status shows three ways (chip text, chip colour, top strip) */
.item-tiles { list-style: none; margin: 0; padding: var(--space-3); display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.item-tiles__cell { display: flex; flex-direction: column; min-width: 0; container-type: inline-size; }
.item-tile { flex: 1; display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; min-height: 148px;
  padding: var(--space-3); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-top: 6px solid var(--c-strip-grey); border-radius: var(--radius-xl); color: var(--c-text);
  text-decoration: none; transition: box-shadow 0.15s ease, border-color 0.15s ease; }
a.item-tile:hover { color: var(--c-text); border-left-color: var(--c-accent); border-right-color: var(--c-accent);
  border-bottom-color: var(--c-accent); box-shadow: var(--shadow-raised); }
.item-tile:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.item-tile--red { border-top-color: var(--c-strip-red); }
.item-tile--amber { border-top-color: var(--c-strip-amber); }
.item-tile--green { border-top-color: var(--c-strip-green); }
.item-tile--grey { border-top-color: var(--c-strip-grey); }
/* Batch 12 E-2 (option 2): good practice has a DASHED strip, legal a solid one, both 6px so tiles stay level */
.item-tile--dashed { border-top-style: dashed; }
.item-tile__top { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
  gap: var(--space-2); }
/* Narrow tiles (2 per row on small phones): the chip always goes under the icon, so every tile looks the same */
@container (max-width: 170px) { .item-tile__top { flex-direction: column; align-items: flex-start; } }
.item-tile__icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 40px;
  height: 40px; border-radius: var(--radius-lg); background: var(--c-accent-bg); color: var(--c-accent); }
.item-tile__name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden; font-size: 0.9375rem; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.item-tile__kind { font-size: 0.75rem; color: var(--c-text-2); }
.item-tile__due { margin-top: auto; font-size: 0.75rem; line-height: 1.45; overflow-wrap: anywhere; }
.item-tiles__cell--files .item-tile { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.item-tile__files { padding: var(--space-2); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-top: 0; border-radius: 0 0 var(--radius-xl) var(--radius-xl); }

/* Empty state */
.empty { color: var(--c-text-2); }
div.empty, li.empty { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-5); }
.empty .icon { color: var(--c-dashed); }
.empty p { margin: 0; }

/* Tabs */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--c-line); overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch; }
.tabs::-webkit-scrollbar { display: none; }
.tabs__tab, .tabs a { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--space-4);
  border-bottom: 3px solid transparent; color: var(--c-text-2); font-weight: 600; text-decoration: none; white-space: nowrap; }
.tabs__tab:hover, .tabs a:hover { color: var(--c-link-hover); }
.tabs__tab:focus-visible, .tabs a:focus-visible { outline-offset: -2px; }
.tabs__tab[aria-current="page"], .tabs a.on { color: var(--c-heading); border-bottom-color: var(--c-primary); }
/* Small phones: tighter tabs; the property tabs scroll sideways if they do not fit (the page itself never does) */
@media (max-width: 479px) {
  .tabs { gap: 0; }
  .tabs__tab, .tabs a { padding: 0 var(--space-2); font-size: 0.875rem; }
}
/* Batch 20 F-33: every tab shows. From 480px (tablet and laptop) the tabs wrap onto a second row when they do not fit:
   no sideways scroll, nothing hidden. Phones keep the sideways swipe; .tabs-wrap--more-start / --more-end (set by
   app.js setupTabs) add a fade over the edge that has more tabs and show that edge's .tabs-arrow button (44px, scrolls
   by most of a screen, smoothly unless reduced motion is asked for). Tokens only, no gradient (the design rule): the
   fade is the page colour under the arrow, blurred outwards by a box shadow of the same colour. */
.tabs-wrap { position: relative; }
.tabs-arrow { position: absolute; top: 0; z-index: 2; display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); padding: 0; border: 0; background: none; color: var(--c-heading); cursor: pointer; }
.tabs-arrow[hidden] { display: none; }
.tabs-arrow--prev { left: 0; justify-content: flex-start; }
.tabs-arrow--next { right: 0; justify-content: flex-end; }
.tabs-arrow:focus-visible { outline-offset: -2px; }
.tabs-wrap::before, .tabs-wrap::after { content: ""; position: absolute; top: 0; bottom: 1px; z-index: 1; width: var(--tap);
  background: var(--c-ground); pointer-events: none; opacity: 0; }
.tabs-wrap::before { left: 0; box-shadow: 0.75rem 0 1rem 0.25rem var(--c-ground); }
.tabs-wrap::after { right: 0; box-shadow: -0.75rem 0 1rem 0.25rem var(--c-ground); }
.tabs-wrap--more-start::before, .tabs-wrap--more-end::after { opacity: 1; }
@media (min-width: 480px) {
  .tabs { flex-wrap: wrap; overflow-x: visible; }
  .tabs-arrow { display: none; }
  .tabs-wrap::before, .tabs-wrap::after { display: none; }
}

/* Flash messages and banners */
.flash { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-3) var(--space-4);
  background: var(--c-card); border: 1px solid var(--c-card-border); border-left: 4px solid var(--c-ok); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card); }
.flash p { margin: 0; }
.flash .icon { margin-top: 2px; }
.flash--ok .icon { color: var(--c-ok); }
.flash--error { border-left-color: var(--c-overdue); }
.flash--error .icon { color: var(--c-overdue); }
.flash--error p { color: var(--c-heading); }
.flash--warn { border-left-color: var(--c-soon); background: var(--c-neutral-bg); }
.flash--warn .icon, .flash--warn p { color: var(--c-soon); }
.flash--info { border-left-color: var(--c-accent); }
.flash--info .icon { color: var(--c-accent); }
.banner { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg); }
.banner.warn { background: var(--c-neutral-bg); color: var(--c-soon); box-shadow: inset 0 0 0 1.5px var(--c-soon); }
.banner.warn a { color: var(--c-soon); font-weight: 600; }
.banner[hidden], [data-deposit-protected][hidden], [data-deposit-files][hidden], [data-lease-fields][hidden], .hint[hidden] { display: none; }
/* Batch 12 E-9 (F1 review I-1): the Done by name box and tenant choice are .stack (display: grid), which would
   override the hidden attribute app.js sets */
[data-done-by-name][hidden], [data-done-by-tenant][hidden] { display: none; }
.auth-card .banner, .auth-card .flash { margin-bottom: var(--space-4); }

/* Buttons */
.btn, button { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  min-height: var(--tap); padding: 0 var(--space-4); border: 1px solid var(--c-field-border); border-radius: var(--radius-md);
  background: transparent; color: var(--c-text); font: inherit; font-weight: 600; font-size: 0.9375rem;
  text-decoration: none; cursor: pointer; }
.btn:hover, button:hover { color: var(--c-heading); border-color: var(--c-accent); background: var(--c-tint); }
.btn--primary { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-primary); font-weight: 700; }
.btn--primary:hover { background: var(--c-primary-hover); border-color: var(--c-primary-hover); color: var(--c-on-primary); }
/* F-79: every secondary button is a lime outline with lime text and no fill, so it stays visible on navy and the app looks consistent. */
.btn--secondary { background: transparent; border-color: var(--c-primary); color: var(--c-primary); }
.btn--secondary:hover { border-color: var(--c-primary-hover); color: var(--c-primary-hover); }
/* Copy buttons and the Register Cancel are auxiliary, so they keep the quiet neutral outline. */
.btn--secondary[data-copy], .btn--secondary[data-copy-value], .btn--secondary[data-details-close] { border-color: var(--c-field-border); color: var(--c-text); }
.btn--danger { background: transparent; border-color: var(--c-danger-border); color: var(--c-heading); }
.btn--danger:hover { border-color: var(--c-overdue-bg); color: var(--c-on-overdue); background: var(--c-overdue-bg); }
.btn--dashed { justify-content: space-between; width: 100%; min-height: 52px; padding: 0 18px; border: 1px dashed var(--c-dashed);
  border-radius: var(--radius-xl); background: var(--c-card); color: var(--c-link); }
.btn--dashed:hover { color: var(--c-link-hover); border-color: var(--c-accent); }
button.link { display: inline; min-height: 0; padding: 0; border: 0; background: none; color: var(--c-link);
  font-weight: inherit; text-decoration: underline; }
button.link:hover { background: none; color: var(--c-link-hover); }
button:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.btn--block { width: 100%; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.actions a:not(.btn) { display: inline-flex; align-items: center; min-height: var(--tap); }

/* Forms */
.stack { display: grid; gap: 14px; }
/* L26 review I1: a hidden .stack never displays (display: grid beat the hidden attribute, as on the Contacts form in
   F-80). */
.stack[hidden] { display: none; }
.narrow { max-width: 420px; }
label { display: grid; gap: var(--space-1); font-weight: 600; }
label small, .hint { font-weight: 400; font-size: 0.875rem; color: var(--c-text-2); }
.hint { display: block; margin-top: -0.5rem; }
label.check { display: flex; align-items: center; gap: var(--space-2); min-height: var(--tap); font-weight: 400; }
input, select, textarea { width: 100%; min-height: var(--tap); padding: 10px var(--space-3); border: 1px solid var(--c-field-border);
  border-radius: var(--radius-md); background: var(--c-field-bg); color: var(--c-text); font: inherit; }
input:focus-visible, select:focus-visible, textarea:focus-visible { border-color: var(--c-focus); }
input::placeholder, textarea::placeholder { color: var(--c-text-2); opacity: 1; }
input[type=checkbox], input[type=radio] { width: 22px; min-height: 22px; accent-color: var(--c-primary); }
input[type=file] { padding: var(--space-2); }
input[type=date] { min-width: 0; }
input::-webkit-date-and-time-value { text-align: left; }
option { background-color: var(--c-field-bg); color: var(--c-text); }
textarea { min-height: 96px; }
fieldset { margin: 0; padding: var(--space-3) var(--space-4) var(--space-4); border: 1px solid var(--c-line); border-radius: var(--radius-lg); }
legend { padding: 0 var(--space-1); font-weight: 700; }
.field-error { color: var(--c-heading); font-size: 0.875rem; font-weight: 600; }
[aria-invalid="true"] { border-color: var(--c-overdue); }

/* Padded cards, the item screen and other T2 components */
.card--pad { padding: var(--space-5); }
.card--pad > :first-child { margin-top: 0; }
.card--pad > :last-child { margin-bottom: 0; }
.card--accent { background: var(--c-tint); border-left: 4px solid var(--c-accent); }
.card__h { margin: 0 0 var(--space-3); font-size: 1.06rem; font-weight: 700; }
.entry { display: flex; flex-direction: column; gap: 14px; }
.entry > * { margin: 0; }
.entry__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.entry__head h2 { margin: 0; font-size: 1.06rem; }
.facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); margin: 0; }
.facts__item { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.facts__item--wide { grid-column: 1 / -1; }
/* L26: the EICR result block (C1, C2, FI side by side from 480px) and an amber field (Unsatisfactory, a field read
   but not certain). Licence conditions as a short list on the item page. */
.eicr-counts { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); }
@media (min-width: 480px) { .eicr-counts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.field--amber { border-color: var(--c-border-orange); }
.licence-conditions { margin: 0; padding-left: var(--space-4); }
/* L26: "Check on the Gas Safe Register" (44px), on its own line under the Gas Safe number hint and on the item page.
   The same body as .council-tax-link (F-96), kept apart because test_f96_council_tax pins that selector list. */
.gas-safe-link { display: inline-flex; align-items: center; align-self: flex-start; justify-self: start;
  min-height: var(--tap); font-size: 0.875rem; }
.facts dt { font-size: 0.75rem; color: var(--c-text-2); }
.facts dd { margin: 0; font-size: 0.9375rem; overflow-wrap: anywhere; }
/* Batch 7c: the mortgage account number, masked; Show reveals it (details without JS, a Show / Hide button with JS) */
.facts dd.account { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-3); }
details.account-reveal { padding: 0; background: none; border: 0; box-shadow: none; }
details.account-reveal > summary { display: inline-flex; padding: 0 var(--space-2); color: var(--c-link); cursor: pointer; }
details.account-reveal[open] > summary { display: none; }
.account-reveal__btn { min-height: var(--tap); }
.file-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.file-row { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: var(--space-3);
  border-radius: var(--radius-md); background: var(--c-tint); color: var(--c-text); text-decoration: none; font-size: 0.875rem; }
.file-row .icon { color: var(--c-accent); }
.file-row span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.file-row small { display: block; color: var(--c-text-2); }
/* F-69: the plain note under a file Tina could not read (presenters.tina_note). */
.file-note { display: block; margin-top: 2px; color: var(--c-text-2); }
a.file-row:hover { color: var(--c-text); text-decoration: underline; }
.btn-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.btn-pair .btn { padding: var(--space-2) var(--space-3); text-align: center; font-size: 0.875rem; }

/* Disclosures: generic details card, the dashed "Add a new ..." button and rows inside a card */
details { padding: var(--space-3) var(--space-4); background: var(--c-card); border: 1px solid var(--c-card-border); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card); }
details > summary { min-height: var(--tap); display: flex; align-items: center; gap: var(--space-2); font-weight: 600;
  list-style: none; cursor: pointer; }
details > summary::-webkit-details-marker { display: none; }
details > summary > .icon:last-child { margin-left: auto; transition: transform 0.15s; }
details[open] > summary > .icon:last-child { transform: rotate(180deg); }
details.add-entry { padding: 0; background: none; border: 0; box-shadow: none; }
details.add-entry > summary { min-height: 52px; padding: 0 18px; border: 1px dashed var(--c-dashed); border-radius: var(--radius-xl);
  background: var(--c-card); color: var(--c-link); }
details.add-entry > summary:hover { border-color: var(--c-accent); color: var(--c-link-hover); }
details.add-entry[open] > summary { border-style: solid; border-color: var(--c-line); border-radius: var(--radius-xl) var(--radius-xl) 0 0; }
.add-entry__body { padding: var(--space-5); background: var(--c-card); border: 1px solid var(--c-card-border); border-top: 0;
  border-radius: 0 0 var(--radius-xl) var(--radius-xl); box-shadow: var(--shadow-card); }
.card details { padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
details.row-details { border-bottom: 1px solid var(--c-line-soft); }
details.row-details:last-child { border-bottom: 0; }
details.row-details > summary { min-height: 48px; padding: 0 18px; font-weight: 400; }
details.row-details > summary:focus-visible { outline-offset: -2px; }
.row-details__meta { margin-left: auto; font-size: 0.8125rem; color: var(--c-text-2); text-align: right; }
.row-details__body { padding: 0 18px var(--space-4); }
.row-details__body > :first-child { margin-top: 0; }
.row-details__body > :last-child { margin-bottom: 0; }
.row-details__body .list-row { padding-left: 0; padding-right: 0; }

/* Tenants, back links, wizard progress, notices */
.tenant-card { --tenant-label-col: 7rem; margin-bottom: var(--space-2); padding: var(--space-3) var(--space-4); background: var(--c-tint); border-radius: var(--radius-md); }
/* Batch 7b S6: a person icon on every tenant card; the lead tenant comes first with the "Lead tenant" chip (the
   words say it; grey neutral pair, already in the contrast test). Batch 10 final: the letting agent card has the
   same icon gutter (handshake), so its values line up with the tenants' */
.tenant-card:not(.ll-card), .agent-card { display: flex; align-items: flex-start; gap: var(--space-3); }
.tenant-card__icon { display: inline-flex; flex: none; margin-top: 2px; color: var(--c-accent); }
.tenant-card__main { flex: 1; min-width: 0; }
.chip--lead { display: inline-flex; margin-bottom: var(--space-2); background: var(--c-neutral-bg); color: var(--c-neutral); }
/* Batch 10 D8: one fixed label column on every tenant card (wide enough for "Second email" and "Letting agent"),
   so the values line up across cards */
.tenant-card dl { display: grid; grid-template-columns: var(--tenant-label-col) minmax(0, 1fr); gap: 2px var(--space-3); margin: 0; }
.tenant-card dt { color: var(--c-text-2); font-size: 0.875rem; }
.tenant-card dd { margin: 0; overflow-wrap: anywhere; }
/* Phones: the label sits above its value (same on every card), so emails keep a full line */
@media (max-width: 479px) {
  .tenant-card dl { grid-template-columns: minmax(0, 1fr); }
  .tenant-card dd + dt { margin-top: var(--space-2); }
}
.tenant-card .actions { margin: var(--space-2) 0 0; }
.tenant-card.former { opacity: 0.85; }
.ll-card { display: grid; gap: var(--space-3); margin-bottom: var(--space-3); }
.ll-card dl, .ll-card form { margin: 0; }
/* L30: the home address block shows only when "No" is chosen (no script needed). */
.ll-form:has(input[name=home_same_as_address][value=yes]:checked) .ll-home { display: none; }
.signature-preview { display: block; max-width: min(100%, 280px); max-height: 120px; padding: var(--space-2);
  background: var(--c-on-dark); border-radius: var(--radius-md); }
.crumbs { margin: 0; }
.crumbs a { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 600; text-decoration: none; }
.crumbs a:hover { text-decoration: underline; }
.progress { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-1) var(--space-4); margin: 0; }
.progress__label { font-weight: 600; color: var(--c-text); }
.progress__bar { display: block; width: 100%; height: 6px; min-height: 0; margin: var(--space-2) 0 0; padding: 0; border: 0;
  border-radius: var(--radius-pill); background: var(--c-line); color: var(--c-primary); overflow: hidden;
  -webkit-appearance: none; appearance: none; }
.progress__bar::-webkit-progress-bar { background: var(--c-line); border-radius: var(--radius-pill); }
.progress__bar::-webkit-progress-value { background: var(--c-primary); border-radius: var(--radius-pill); }
.progress__bar::-moz-progress-bar { background: var(--c-primary); border-radius: var(--radius-pill); }
.banner--info { background: var(--c-card); color: var(--c-text); border: 1px solid var(--c-card-border); border-left: 4px solid var(--c-accent);
  box-shadow: var(--shadow-card); }
.banner p { margin: 0; }
.banner .icon { align-self: flex-start; margin-top: 2px; }
.qr { padding: var(--space-2); background: var(--c-qr-bg); border: 1px solid var(--c-line); border-radius: var(--radius-sm); }  /* light so phones can scan it */
.wizard-head { display: grid; gap: var(--space-1); }
.wizard-head .actions { margin: 0; }
.qr-wrap { margin: var(--space-4) 0; }
.auth-card .error-card { padding: 0; border: 0; box-shadow: none; }
.steps { margin: 0; padding-left: 1.25rem; }
.steps li + li { margin-top: var(--space-2); }
.error-card { display: flex; align-items: flex-start; gap: var(--space-3); }
.error-card > .icon { margin-top: 4px; color: var(--c-overdue); }
.error-card h1 { margin-bottom: var(--space-2); font-size: 1.3rem; }

/* Form layout: primary button bottom-right on laptop, full width on phone */
.form-actions { display: flex; flex-direction: column-reverse; align-items: stretch; gap: var(--space-2) var(--space-4); margin-top: var(--space-2); }
.form-actions .btn { width: 100%; }
.form-actions > a:not(.btn) { display: inline-flex; align-items: center; justify-content: center; min-height: var(--tap); font-weight: 600; }
.field-error { display: flex; align-items: center; gap: var(--space-1); }
input:user-invalid, select:user-invalid, textarea:user-invalid { border-color: var(--c-overdue); }
.code-input { font-family: var(--font-mono); font-size: 1.25rem; letter-spacing: 0.4em; text-align: center; }
/* File picker: with JS the native input is visually hidden (still focusable) behind a "Choose files" button */
.file-picker { position: relative; }
.file-picker__button { display: none; }
.js .file-picker__button { display: inline-flex; margin-top: var(--space-2); }
.js .file-picker input[type=file] { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.js .file-picker__label:focus-within .file-picker__button { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.file-picker__status { margin: var(--space-2) 0; font-weight: 600; }
.file-picker__status[hidden], .file-picker__status:empty { display: none; }
.chosen-files { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.chosen-files:empty, .upload-status:empty { display: none; }
.chosen-files li { display: flex; align-items: center; gap: var(--space-3); min-height: var(--tap); padding: var(--space-2) var(--space-3);
  background: var(--c-tint); border-radius: var(--radius-md); font-size: 0.875rem; }
.chosen-files img { flex: none; width: 48px; height: 48px; object-fit: cover; border: 1px solid var(--c-line);
  border-radius: var(--radius-sm); }
.chosen-files span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.chosen-files button { flex: none; color: var(--c-heading); border-color: var(--c-danger-border); }
.plain-list { list-style: none; margin: 0; padding: 0; }

/* Rules: a table in a card on laptop; each rule a stacked card on phones */
table.rules { width: 100%; border-collapse: collapse; }
table.rules th { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-line); text-align: left; font-size: 0.7rem;
  font-weight: 600; letter-spacing: 1.2px; text-transform: uppercase; color: var(--c-text-2); }
table.rules td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-line-soft); text-align: left;
  vertical-align: top; overflow-wrap: anywhere; }
table.rules tr:last-child td { border-bottom: 0; }
table.rules td small { display: block; margin-top: 2px; color: var(--c-text-2); font-size: 0.8125rem; }

@media (max-width: 899px) {
  /* The phone header already shows the short address. */
  .prop-head { display: none; }
  /* Menu panel top row: the brand and "Close menu" must fit the panel (320px, 90% of narrower screens) without sideways scroll */
  .sidebar { width: min(320px, 90vw); padding-left: var(--space-3); padding-right: var(--space-3); }
  .sidebar__top { gap: var(--space-1); }
  .sidebar__top .brand { gap: var(--space-2); padding: 0; font-size: 1rem; }
  /* "Close menu" stays on one line at 360px (icon + text, tight spacing; the accessible name is unchanged) */
  .menu-close { min-width: 0; gap: 2px; padding: 0 6px; font-size: 0.875rem; white-space: nowrap; }
  .rules-card { background: none; border: 0; box-shadow: none; border-radius: 0; overflow: visible; }
  .rules-card > .card__head { padding: 0 0 var(--space-3); border-bottom: 0; }
  table.rules, table.rules tbody, table.rules tr, table.rules td { display: block; width: 100%; }
  table.rules thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.rules tr { margin-bottom: var(--space-3); padding: var(--space-2) 0; background: var(--c-card); border: 1px solid var(--c-card-border);
    border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
  table.rules td { padding: var(--space-1) var(--space-4); border: 0; }
  table.rules td[data-label]::before { content: attr(data-label); display: block; font-size: 0.75rem; color: var(--c-text-2); }
}
@media (min-width: 700px) {
  .form-actions { flex-direction: row; justify-content: flex-end; align-items: center; }
  .form-actions .btn { width: auto; }
  .form-actions--wizard > :first-child { margin-right: auto; }  /* Back on the left (batch 12 E-8) */
  .card--pad { padding: var(--space-6); }
}
@media (min-width: 900px) {
  .topbar, .menu-btn, .menu-close, .scrim { display: none; }
  .shell.with-nav { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); align-items: start; }
  .sidebar { position: sticky; top: 0; height: 100vh; width: auto; z-index: auto; transform: none; visibility: visible;
    transition: none; padding: var(--space-6) var(--space-4); }
  .sidebar:target { box-shadow: none; }
  .shell.with-nav main { padding: var(--space-8) 40px; gap: var(--space-6); }
  h1, .page-head h1 { font-size: 1.75rem; }
  .tiles { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-4); }
  .item-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); padding: var(--space-4) var(--space-5); }
  .item-tile { padding: var(--space-4); }
  .auth-shell { align-items: center; }
}
@media (prefers-reduced-motion: reduce) { .sidebar { transition: none; } }

/* Tenancy documents panel */
.doc-slot { display: grid; gap: var(--space-3); }
.doc-slot__title { margin: 0; font-size: 1rem; font-weight: 600; }
.doc-slot .empty { padding: var(--space-2) 0; }
.doc-slot__from { margin: var(--space-1) 0 0; padding-left: var(--space-3); font-size: 0.875rem; color: var(--c-text-2); }
.doc-slot__from a { display: flex; align-items: center; width: max-content; max-width: 100%; min-height: var(--tap); }
details.add-entry--slot > summary { min-height: var(--tap); }
.tenancy-docs .card__foot { margin: 0; }
.on-file { display: flex; align-items: flex-start; gap: var(--space-1); margin: 0; overflow-wrap: anywhere; }
.on-file .icon { flex: none; margin-top: 0.7rem; color: var(--c-text-2); }
.on-file a { display: inline-flex; align-items: center; min-height: var(--tap); }

/* Item screen: Earlier versions (F-75): one list of edited, earlier and deleted entries, a Restore on a deleted one */
.entry__earlier { margin: var(--space-3) 0 0; font-size: 0.875rem; }
.entry__earlier a { display: inline-flex; align-items: center; min-height: var(--tap); }
.earlier-versions__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.earlier-version { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2) var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--c-line-soft); }
.earlier-version:first-child { padding-top: 0; border-top: 0; }
.earlier-version p { margin: 0; }
.earlier-version__title { font-weight: 600; }
.earlier-version__line { font-size: 0.875rem; color: var(--c-text-2); }
.earlier-version--deleted .earlier-version__title { color: var(--c-text-2); }
.earlier-version .file-list { flex-basis: 100%; }

/* Documents tab archive: search, sections, groups by item or tenancy, "Earlier (n)" */
.archive-search { display: grid; gap: var(--space-2); }
.archive-search label { font-weight: 600; }
.archive-search__row { display: flex; gap: var(--space-2); }
.archive-search__row input { flex: 1; min-width: 0; }
.archive-search .hint { margin: 0; }
.archive-section { display: grid; gap: var(--space-4); padding: var(--space-5); }
.archive-group { display: grid; gap: var(--space-2); }
.archive-group + .archive-group { padding-top: var(--space-4); border-top: 1px solid var(--c-line-soft); }
.archive-group__title { margin: 0; font-size: 1rem; font-weight: 600; }
.archive-group__title small { display: block; font-size: 0.875rem; font-weight: 400; color: var(--c-text-2); }
.archive-group__link { margin: 0; }
.archive-group__link a { display: inline-flex; align-items: center; min-height: var(--tap); }
.archive .doc-slot { gap: var(--space-2); }
.archive .hint { margin: 0; }
.archive .empty { padding: var(--space-2) 0; }
details.archive-earlier > summary { font-weight: 400; color: var(--c-link); }
details.archive-earlier[open] > summary, details.archive-mistakes[open] > summary { margin-bottom: var(--space-2); }
details.archive-mistakes > summary h2 { margin: 0; }
[data-file-name][hidden], [data-file-group][hidden], [data-file-section][hidden], [data-no-match][hidden] { display: none; }

/* Mortgage section (batch 15b J1 data, batch 19 F-29 grid, board O). .mortgage-question: the two radios with a Save
   button (the "No mortgage" radio is disabled, with the reason in a hint, while a mortgage is in force or to come);
   .banner.error is the red "Mortgage details" line, the words say it. table.mortgage-grid: one tbody per row
   (.mortgage-grid__row --current --next --ended --other) with the values and a second line (.mortgage-grid__status)
   holding the state chip in words and the migrated row's "check it" hint; tbody.mortgage-grid__gap is a gap (red
   alert icon and words); .mortgage-grid__actions holds Edit and, on the latest row, Remove (44px tall links). Below
   1100px each tbody is a stacked card, each value labelled from td[data-label]. Rows corrected or removed are in
   details.mortgage-card__errors, struck through. */
.banner.error { background: var(--c-overdue-bg); color: var(--c-on-overdue); }
.mortgage-card__alert { margin: 0 var(--space-4) var(--space-3); }
.mortgage-card__none { color: var(--c-heading); }
.mortgage-card__none .icon { color: var(--c-overdue); }
.mortgage-question { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4);
  margin: 0 var(--space-4) var(--space-3); padding-bottom: var(--space-3); border-bottom: 1px solid var(--c-line); }
.mortgage-question__set { display: flex; flex-wrap: wrap; gap: 0 var(--space-6); margin: 0; padding: 0; border: 0; }
.mortgage-question__choice { min-height: var(--tap); margin: 0; }
.mortgage-question .hint { flex-basis: 100%; margin: 0; }
.mortgage-card__text { margin: 0 var(--space-4) var(--space-3); }
.mortgage-card__add { margin: 0 var(--space-4) var(--space-4); }
.mortgage-card__errors { margin: 0 var(--space-4) var(--space-4); }
.mortgage-card__error s { color: var(--c-text-2); }
.mortgage-grid-box { margin: 0 var(--space-4) var(--space-2); }
table.mortgage-grid { width: 100%; border-collapse: collapse; }
table.mortgage-grid th { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--c-line); text-align: left;
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.04em; color: var(--c-text-2); }
table.mortgage-grid td { padding: var(--space-3); text-align: left; vertical-align: top; font-size: 0.875rem;
  overflow-wrap: anywhere; }
.mortgage-grid__row td { border-top: 1px solid var(--c-line); }
.mortgage-grid__row .mortgage-grid__status td { border-top: 0; padding-top: 0; }
.mortgage-grid__status td { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.mortgage-grid__hint { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--c-soon); }
.mortgage-grid__confirm { margin: 0; }
.mortgage-grid__actions { white-space: nowrap; }
.mortgage-grid__actions a { display: inline-flex; align-items: center; min-height: var(--tap); margin-right: var(--space-4); }
.mortgage-grid__gap td { border-top: 1px solid var(--c-line); color: var(--c-heading); }
.mortgage-grid__gap td > span { margin-left: var(--space-2); }
.mortgage-grid__gap .icon { color: var(--c-overdue); vertical-align: -3px; }
@media (max-width: 1099px) {
  table.mortgage-grid, table.mortgage-grid tbody, table.mortgage-grid tr, table.mortgage-grid td { display: block; width: 100%; }
  table.mortgage-grid thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.mortgage-grid tbody { margin-bottom: var(--space-3); padding: var(--space-2) 0; background: var(--c-ground);
    border: 1px solid var(--c-line); border-radius: var(--radius-xl); }
  table.mortgage-grid td { padding: var(--space-1) var(--space-3); border: 0; }
  .mortgage-grid__row td { border-top: 0; }
  table.mortgage-grid td[data-label] { display: flex; gap: var(--space-3); }
  table.mortgage-grid td[data-label]::before { content: attr(data-label); flex: 0 0 7.5rem; color: var(--c-text-2); }
  .mortgage-grid__row .mortgage-grid__status td { padding-top: var(--space-1); }
  .mortgage-grid__actions { white-space: normal; }
  .mortgage-grid__gap td { border-top: 0; }
}
.pre-line { white-space: pre-line; }

/* Evidence packs (batch 19 X2, board P). .evidence-card: the group under Tenancy details on a tenancy's Summary tab
   (.group-title heading, a .card__body with the intro hint, ul.pack-list or .evidence-card__empty, and the secondary
   "Create evidence pack"). li.pack-row (--queued --running --ready --failed): an icon (.pack-row__spinner while
   preparing: a turning ring, still under prefers-reduced-motion, the words say it), .pack-row__text (strong title,
   small lines) and the Download button. The form page: form.pack-form (fieldsets .pack-form__types with each type's
   contents under its name, .pack-form__date-row side by side, details.pack-form__sections with .pack-form__checks in
   two columns from 700px, .pack-form__notes). */
.evidence-card__body > .hint { margin-top: 0; }
.evidence-card__empty { margin: 0; color: var(--c-text-2); }
.evidence-card__actions { margin: var(--space-3) 0 0; }
.pack-list { margin: 0; }
.pack-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0;
  border-top: 1px solid var(--c-line); }
.pack-row__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.pack-row__text small { color: var(--c-text-2); }
.pack-row__icon { flex: none; color: var(--c-accent); }
.pack-row__icon--failed { color: var(--c-overdue); }
.pack-row__error { color: var(--c-heading); }
.pack-row__download { flex: none; }
.pack-row__spinner { flex: none; width: 18px; height: 18px; border-radius: 50%; border: 3px solid var(--c-line);
  border-top-color: var(--c-accent); animation: pack-spin 1s linear infinite; }
@keyframes pack-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pack-row__spinner { animation: none; } }
@media (max-width: 480px) {
  .pack-row { flex-wrap: wrap; }
  .pack-row__download { margin-left: calc(18px + var(--space-3)); }
}
.pack-form fieldset { margin: 0; }
.pack-form__type { align-items: flex-start; }
.pack-form__type > span { display: flex; flex-direction: column; gap: 2px; }
.pack-form__date-row { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6); }
.pack-form__date-row label { flex: 1 1 12rem; }
.pack-form__checks { display: grid; grid-template-columns: 1fr; gap: 0 var(--space-5); }
@media (min-width: 700px) { .pack-form__checks { grid-template-columns: 1fr 1fr; } }
.pack-form__notes { margin-top: var(--space-2); }

/* Sidebar: tenancies of the viewed property, nested under it (batch 4 item 6). Long names wrap (no h-scroll). */
.nav-sub { list-style: none; margin: 2px 0 var(--space-1); padding: 0 0 0 var(--space-4); display: flex;
  flex-direction: column; gap: 2px; }
.nav-sub a { min-height: var(--tap); padding: var(--space-2) var(--space-3); font-size: 0.875rem; line-height: 1.3;
  color: var(--c-nav-soft); border-left: 2px solid var(--c-nav-active); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.nav-list .nav-sub a[aria-current="true"] { background: var(--c-nav-active); color: var(--c-on-dark); font-weight: 600;
  border-left-color: var(--c-nav-current); }
details.nav-earlier { padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
details.nav-earlier > summary { padding: 0 var(--space-3); font-size: 0.875rem; font-weight: 400; color: var(--c-nav-muted);
  border-radius: var(--radius-sm); }
details.nav-earlier > summary:hover { background: var(--c-nav-active); color: var(--c-on-dark); }
details.nav-earlier > .nav-sub { padding-left: 0; }

/* Property page for a past tenancy */
.past-banner .card__title { margin: 0; }
.past-banner p { margin: var(--space-2) 0 0; }
.past-banner a { display: inline-flex; align-items: center; min-height: var(--tap); }
.tenancy-people { display: grid; gap: var(--space-3); }
.cover-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); padding: var(--space-3); }
.building-cover .cover { display: grid; gap: var(--space-2); align-content: start; min-width: 0;
  padding: var(--space-3) var(--space-4); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-top: 4px solid var(--c-strip-grey); border-radius: var(--radius-xl); }
.building-cover .cover--red { border-top-color: var(--c-strip-red); }
@media (min-width: 900px) {
  .cover-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: var(--space-4) var(--space-5); }
}
.cover__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.cover__title { margin: 0; font-size: 1rem; font-weight: 600; }
.cover__title a { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--c-text); }
.cover__entries, .cover__gaps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.cover__facts { margin: 0 0 var(--space-1); }
.cover__entries .hint { margin: 0; }
.cover__gaps li { display: flex; align-items: flex-start; gap: var(--space-2); padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm); background: var(--c-overdue-bg); color: var(--c-on-overdue); font-weight: 600; }
.cover__gaps .icon { flex: none; margin-top: 2px; }
.cover__gaps--good-practice li { background: var(--c-neutral-bg); color: var(--c-neutral); }  /* good practice stays grey */

/* Batch 10 E2 (list D D3, D6, D7): group headings inside the Summary tab tenancy cards (Tenants, Tenancy details,
   At Tenancy Start, At Tenancy End): an h3 under the card's h2, accent icon + text */
.group-title { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-4) 0 var(--space-2);
  font-size: 1rem; font-weight: 700; line-height: 1.35; color: var(--c-heading); overflow-wrap: anywhere; }
.group-title__icon { display: inline-flex; flex: none; color: var(--c-accent); }
.card--tiles > .card__head + .group-title { margin-top: 0; }

/* Tenancy details tile (batch 7b S7): icon + label + value rows, 1 column on phones, 2 from 900px; links below */
.details-tile__grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3) var(--space-5); margin: 0; }
.details-tile__row { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.details-tile__row dt { display: flex; align-items: center; gap: var(--space-2); font-size: 0.8125rem; color: var(--c-text-2); }
.details-tile__row dd { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-1); margin: 0 0 0 28px;
  font-weight: 600; overflow-wrap: anywhere; }
.details-tile__icon { display: inline-flex; flex: none; color: var(--c-accent); }
.details-tile__advice { min-width: 0; }  /* batch 9 C1: the sentences stay one flowing item in the flex dd */
/* Batch 22 R3 (F-46): "Notice created: ..., not served yet" (amber) or "Too late to serve ..." (red), a 44px link to
   the Rent tab; the words say the state, the icon and colour only repeat it. */
.details-tile__notice { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap);
  min-width: 0; }
.details-tile__notice .icon { flex: none; }
.details-tile__notice--due-soon .icon { color: var(--c-soon); }
.details-tile__notice--overdue .icon { color: var(--c-overdue); }
.details-tile__links { margin: var(--space-4) 0 0; padding-top: var(--space-2); border-top: 1px solid var(--c-line-soft); }
@media (min-width: 900px) {
  .details-tile__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Batch 7b S8: "+ Add tenancy" beside the This tenancy heading; the row wraps on narrow phones */
.card__head:has(> .card__action) { flex-wrap: wrap; }
.card__action { flex: none; }

/* Rent section and header line on the tenancy card (batch 6 Q3) */
.rent-card__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--space-1) var(--space-3); margin-bottom: var(--space-3); }
.rent-card__head .card__title { margin: 0; }
.rent-card .hint { margin: 0 0 var(--space-3); }
.rent-card__action { margin: var(--space-4) 0 0; }
.rent-card__unsigned { display: flex; align-items: flex-start; gap: var(--space-1); margin: var(--space-2) 0 0;
  overflow-wrap: anywhere; }
.rent-card__unsigned .icon { flex: none; margin-top: 2px; color: var(--c-accent); }
.rent-card__unsigned a { display: inline-flex; align-items: center; min-height: var(--tap); }
.rent-notice__reminder { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2);
  margin: 0; color: var(--c-soon); font-weight: 600; overflow-wrap: anywhere; }
.rent-notice__reminder .icon { flex: none; }
.rent-notice__event { font-weight: 400; }
.calc__sign { display: grid; gap: var(--space-2); min-width: 0; }
.calc__sign p { margin: 0; }
.ll-card__unsigned { font-size: 0.875rem; }
.notice-created { display: grid; gap: var(--space-3); }
.notice-created .actions { margin: 0; }
.rent-section > .card__title { margin: 0; }
.rent-section .rent-notices > .section-title, .rent-section .rent-history > .section-title { margin: var(--space-4) 0 var(--space-1); }
.rent-reminder { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); color: var(--c-text); }
.rent-reminder .icon { color: var(--c-accent); }
.rent-reminder__text { flex: 1 1 12rem; min-width: 0; }
.rent-notices .section-title { margin: var(--space-4) 0 var(--space-1); }
.rent-notice { display: grid; gap: var(--space-2); padding: var(--space-3) 0; }
.rent-notice__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.rent-notice__title { font-weight: 600; }
.rent-notice__facts { margin: 0; padding: 0; list-style: none; font-size: 0.875rem; color: var(--c-text-2); }
.rent-notice__facts li { overflow-wrap: anywhere; }

/* Rent increase calculator (batch 6 Q3): phone first, summary below the inputs; two columns from 1000px */
.calc { display: grid; gap: var(--space-4); }
.calc__inputs { display: grid; gap: 14px; align-content: start; }
.calc__inputs h2 { margin: 0; }
.calc__inputs > label, .calc .label { font-weight: 600; margin-bottom: -6px; }
.calc .label { display: block; margin-bottom: var(--space-1); }
.calc__pair { display: grid; gap: 14px; }
.calc__pair > div { display: grid; gap: var(--space-1); align-content: start; }
.calc__pair .hint { margin-top: 0; }
.calc input[readonly] { background: var(--c-tint); border-style: dashed; }
.seg { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1); padding: var(--space-1); min-height: var(--tap);
  border: 1px solid var(--c-field-border); border-radius: var(--radius-md); background: var(--c-field-bg); }
.seg__opt { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1); padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm); color: var(--c-text-2); font-size: 0.9375rem; }
.seg__opt[aria-current="true"] { background: var(--c-accent-bg); color: var(--c-heading); font-weight: 700; box-shadow: inset 0 0 0 1px var(--c-accent); }
.calc__check { display: grid; gap: var(--space-2); }
.calc__check [hidden] { display: none; }
.calc__broken { display: grid; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius-md); background: var(--c-overdue-bg); color: var(--c-on-overdue); }
.calc__broken ul { margin: 0; padding-left: var(--space-5); }
.calc__broken .btn { justify-self: start; color: var(--c-on-overdue); border-color: var(--c-on-overdue); }
.calc__check-title, .calc__ok { display: flex; align-items: center; gap: var(--space-2); margin: 0; font-weight: 600; }
.calc__ok { color: var(--c-ok); }
.calc__warn { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-2) 0 0; padding: var(--space-2) var(--space-3); border-radius: var(--radius-md); background: var(--c-neutral-bg); color: var(--c-soon); box-shadow: inset 0 0 0 1.5px var(--c-soon); font-weight: 600; }
.calc__warn[hidden] { display: none; }
/* phones: the buttons stack in DOM (tab) order, Check first, then Create */
.calc__actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); }
.calc__actions .btn { width: 100%; }
.calc__summary { display: grid; gap: var(--space-4); align-content: start; }
.calc__label { margin: 0; text-align: center; }
.calc__date { margin: var(--space-1) 0 0; text-align: center; font-size: 1.75rem; line-height: 1.2; font-weight: 700; color: var(--c-heading); }
.calc__reason { margin: var(--space-2) 0 0; text-align: center; color: var(--c-text-2); font-size: 0.9375rem; }
.calc__note { display: flex; gap: var(--space-2); padding: var(--space-3) var(--space-4); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-md); background: var(--c-tint); font-size: 0.875rem; }
.calc__note p { margin: 0; }
.calc__note .icon, .calc__guidance .icon { color: var(--c-accent); margin-top: 2px; }
.calc__table { width: 100%; border-collapse: collapse; border: 1px solid var(--c-card-border); border-radius: var(--radius-md); }
.calc__table th, .calc__table td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--c-line); text-align: left; }
.calc__table tr:last-child th, .calc__table tr:last-child td { border-bottom: 0; }
.calc__table th { font-weight: 400; color: var(--c-text-2); }
.calc__table td { text-align: right; font-weight: 700; overflow-wrap: anywhere; }
.calc__percent { color: var(--c-accent); }
.calc__guidance { display: grid; gap: var(--space-3); margin: 0; padding: 0; list-style: none; font-size: 0.875rem; color: var(--c-text-2); }
.calc__guidance li { display: flex; gap: var(--space-2); }
.calc__guidance p { margin: 0; }
.calc-gaps ul { margin: var(--space-1) 0; padding-left: var(--space-5); }
@media (min-width: 700px) {
  .calc__pair { grid-template-columns: 1fr 1fr; }
  .calc__actions { flex-direction: row; justify-content: flex-end; }
  .calc__actions .btn { width: auto; }
}
@media (min-width: 1000px) {
  .calc { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); align-items: start; }
}

/* Marketing photos (batch 7): a grid of photo cards, 2 per row on phones, 3 or 4 from 700px. Buttons stack full
   width inside a card so they stay 44px tall and never cause sideways scrolling at 360px. */
.photo-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3); }
.photo-card { display: flex; flex-direction: column; min-width: 0; overflow: hidden; background: var(--c-card);
  border: 1px solid var(--c-card-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
.photo-card--main { border-color: var(--c-accent); }
.photo-card:target { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.photo-card__img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover;
  background: var(--c-tint); }
.photo-card__body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); min-width: 0; }
.photo-card__name { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); margin: 0;
  font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.photo-card__label { display: flex; flex-direction: column; gap: var(--space-1); margin: 0; }
.photo-card__label label { font-size: 0.8125rem; font-weight: 600; }
.photo-card__label input { width: 100%; min-width: 0; }
.photo-card__actions { display: flex; flex-direction: column; gap: var(--space-2); }
.photo-card__actions form { margin: 0; }
.photo-card .btn { width: 100%; padding: var(--space-1) var(--space-2); font-size: 0.875rem; text-align: center;
  white-space: normal; }
.photo-upload .hint { margin-top: 0; }
.photo-delete__img { display: block; width: 100%; max-width: 480px; height: auto; margin-bottom: var(--space-4);
  border-radius: var(--radius-lg); }
.photo-download-all { flex: none; }
.advert .hint.advert__count { margin: 0; font-family: var(--font-mono); font-size: 0.8125rem; }
.advert textarea { min-height: 180px; }
.storage-meter { display: grid; gap: var(--space-2); margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--c-line); }
.storage-meter__text { margin: 0; font-size: 0.875rem; color: var(--c-text-2); }
.storage-meter__bar { display: block; width: 100%; height: 6px; min-height: 0; margin: 0; padding: 0; border: 0;
  -webkit-appearance: none; appearance: none; background: var(--c-line); border-radius: var(--radius-pill); }
.storage-meter__bar::-webkit-meter-bar { background: var(--c-line); border: 0; border-radius: var(--radius-pill); }
.storage-meter__bar::-webkit-meter-optimum-value,
.storage-meter__bar::-webkit-meter-suboptimum-value,
.storage-meter__bar::-webkit-meter-even-less-good-value { background: var(--c-accent); border-radius: var(--radius-pill); }
.storage-meter__bar::-moz-meter-bar { background: var(--c-accent); border-radius: var(--radius-pill); }
.storage-meter__warn { margin: 0; }
@media (min-width: 700px) {
  .photo-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--space-4); }
}

/* Repairs (batch 9) */
.tabs__icon { display: inline-flex; margin-right: var(--space-1); color: var(--c-accent); }
.repairs-head__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); }
.repair-filters { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2);
  margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--c-line); }
.repair-filters label { font-size: 0.8125rem; font-weight: 600; }
.repair-filters__clear { display: inline-flex; align-items: center; min-height: var(--tap); }
.repair-list { overflow: hidden; }
.repair-list__title { margin: 0; padding: var(--space-4) var(--space-5) var(--space-2); }
.repair-list__split { margin: 0; padding: 0 var(--space-5) var(--space-2); }
.repair-list > .empty { padding-top: var(--space-2); }
.repair-rows { list-style: none; margin: 0; padding: 0; }
.repair-row { border-top: 1px solid var(--c-line-soft); }
.repair-row:first-child { border-top: 0; }
.row-details__body .repair-row__link { padding-left: 0; padding-right: 0; }
.repair-row__link { display: flex; align-items: flex-start; gap: var(--space-3); min-height: var(--tap);
  padding: var(--space-3) var(--space-5); color: var(--c-text); text-decoration: none; }
.repair-row__link:hover { background: var(--c-tint); color: var(--c-text); }
.repair-row__link:focus-visible { outline-offset: -2px; }
.repair-row__icon, .repair-head__icon { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 40px; height: 40px; border-radius: var(--radius-lg); background: var(--c-accent-bg); color: var(--c-accent); }
.repair-row__main { display: flex; flex-direction: column; gap: var(--space-1); flex: 1; min-width: 0; }
.repair-row__title { font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.repair-row__link:hover .repair-row__title { text-decoration: underline; }
.repair-row__chips, .repair-head__chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.repair-row__category { font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.repair-row__targets { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); font-size: 0.8125rem; }
.repair-row__meta { font-size: 0.75rem; color: var(--c-text-2); }
.repair-target { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-1);
  overflow-wrap: anywhere; }
.repair-target--missed { color: var(--c-heading); font-weight: 600; }
.repair-target--missed .icon { color: var(--c-overdue); }
.repair-target small { flex-basis: 100%; font-size: 0.75rem; font-weight: 400; color: var(--c-text-2); }
.repair-head__icon { margin-right: var(--space-3); vertical-align: middle; }
.repair-head__chips { margin: 0; }
.repair-facts .file-list { margin-top: var(--space-4); }
.repair-facts__added { margin-top: var(--space-3); }
.repair-earlier { margin-top: var(--space-3); border: 1px solid var(--c-line-soft); border-radius: var(--radius-md); }
.repair-round + .repair-round { margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--c-line-soft); }
.repair-round__title { margin: 0 0 var(--space-2); font-size: 0.875rem; font-weight: 600; }
.repair-entries { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.repair-entry { display: grid; gap: var(--space-2); padding: var(--space-3) var(--space-4); min-width: 0;
  background: var(--c-tint); border-radius: var(--radius-md); }
.repair-entry--correction { margin-left: var(--space-4); border-left: 3px solid var(--c-accent); }
.repair-entry p { margin: 0; }
.repair-entry__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3); }
.repair-entry__type { font-weight: 600; color: var(--c-heading); }
.repair-entry__head time, .repair-entry__channel { font-size: 0.8125rem; color: var(--c-text-2); }
.repair-entry__link { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-1); font-size: 0.875rem;
  overflow-wrap: anywhere; }
.repair-entry__link > span { flex: none; }
.repair-entry__link a { display: inline-flex; align-items: center; min-height: var(--tap); }
.repair-entry__note { overflow-wrap: anywhere; }
.repair-entry__added { font-size: 0.75rem; color: var(--c-text-2); }
.repair-entry .file-row { background: var(--c-card); }
.repair-add__access { margin-top: 0; }
.repair-head__stage { margin: 0; font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.repair-add__stage { margin-top: 0; overflow-wrap: anywhere; }
.repair-entry__who { font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.repair-split { font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
[data-who-name][hidden] { display: none; }
[data-show-for][hidden] { display: none; }
/* F-80: the tenancy and property forms' agent pickers (.stack would otherwise override hidden). */
[data-agent-for][hidden] { display: none; }
/* F-101: the OpenRent hint and the letting agent picker sit indented under their radio (board AL). Hiding comes from
   the global .stack[hidden] and .hint[hidden] rules. Tokens only. */
.let-through__more { padding-left: var(--space-4); }
/* F-101: the tenancy card's "How it was let" row (label left, answer right; wraps on a phone) and its 44px Add. */
.how-let { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-2);
  margin: 0; padding: var(--space-2) 0; }
.how-let dt { color: var(--c-text-2); font-size: 0.875rem; }
.how-let dd { margin: 0; font-weight: 600; }
.how-let__none { font-weight: 400; font-style: italic; color: var(--c-text-2); }
.how-let__add { display: inline-flex; align-items: center; min-height: var(--tap); }
/* F-80 (Task 9/10 review): the chosen agent's box under a picker (the tenant card's tint) and the 44px "Edit in
   Contacts" links (picker boxes and the letting agent card). Tokens only. */
.agent-box { display: grid; gap: var(--space-1); padding: var(--space-3) var(--space-4); background: var(--c-tint);
  border-radius: var(--radius-md); overflow-wrap: anywhere; }
.agent-box dl { margin: 0; }
/* Browser check (final review): the picker box's details as the tenant card's labels, without the browser's 40px
   dd indent (it wrapped an email mid-word on a phone). */
.agent-box dt { color: var(--c-text-2); font-size: 0.875rem; }
.agent-box dd { margin: 0 0 var(--space-1); overflow-wrap: anywhere; }
.agent-edit { display: inline-flex; align-items: center; min-height: var(--tap); }
/* The calculator's "The notice will name your letting agent" line: the 44px link on its own line, so it does not
   stretch one line of the sentence. */
[data-notice-agent] .agent-edit { display: flex; width: fit-content; }
.repair-settings__icon { display: inline-flex; margin-right: var(--space-2); color: var(--c-accent); vertical-align: middle; }
@media (min-width: 700px) {
  .repair-filters { grid-template-columns: auto minmax(0, 14rem) auto minmax(0, 16rem) auto auto; align-items: center; }
}

/* F-76: tab intros (rental.web.intros) */
.tab-intro { display: grid; gap: var(--space-2); }
.tab-intro .hint { margin: 0; overflow-wrap: anywhere; }
* + .tab-intro { margin-top: var(--space-3); }
/* F-105 (board AO): the head card every property tab but Summary opens with (the tab_head macro): the tab's icon and
   name, a status line on Timeline and End tenancy (white words in a thin box; the E-11 ending colours as a modifier,
   the words always say the state), then the intro. Tokens only. */
.tab-head__status { display: flex; align-items: center; gap: var(--space-2); width: fit-content; max-width: 100%;
  margin: var(--space-3) 0 0; padding: var(--space-2) var(--space-3); border: 1px solid var(--c-line);
  border-radius: var(--radius-md); color: var(--c-heading); font-weight: 600; overflow-wrap: anywhere; }
.tab-head__status-icon { display: inline-flex; flex: none; color: var(--c-accent); }
.tab-head__status--ending { color: var(--c-soon); }
.tab-head__status--ending .tab-head__status-icon { color: var(--c-strip-amber); }
.tab-head__status--ending-soon .tab-head__status-icon { color: var(--c-strip-red); }
.end-head__past { margin: var(--space-3) 0 0; color: var(--c-text-2); }

/* Messages (batch 16, L18) */
.messages-head__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); }
.messages-head__past { margin-top: var(--space-3); }
/* F-76 (board AE): the filters folded behind "Filter messages" (closed by default, open when a filter is active), and
   the one-line "Filtered: ..." summary with Clear after it, shown whether the box is open or closed. */
.message-filters-bar { margin-top: var(--space-4); padding-top: var(--space-2); border-top: 1px solid var(--c-line); }
.message-filters-box > summary { min-height: var(--tap); color: var(--c-link); }
.message-filters-box > summary:hover { color: var(--c-link-hover); }
.message-filters__active { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-3); margin: 0;
  font-size: 0.875rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.message-filters { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2);
  margin-top: var(--space-2); }
.message-filters label { font-size: 0.8125rem; font-weight: 600; }
.message-filters select, .message-filters input { min-height: var(--tap); min-width: 0; max-width: 100%; }
.message-filters__buttons { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.message-filters__clear { display: inline-flex; align-items: center; min-height: var(--tap); }
.message-filters__note { margin: var(--space-2) 0 0; }   /* not .hint's -0.5rem: it ran under Apply */
.message-list { overflow: hidden; }
.message-list__title { margin: 0; padding: var(--space-4) var(--space-5) var(--space-2); }
.message-list__count { margin: 0; padding: 0 var(--space-5) var(--space-3); }
.message-list__more { margin: 0; padding: var(--space-3) var(--space-5) var(--space-4); }
.message-rows { list-style: none; margin: 0; padding: 0 var(--space-4) var(--space-4); display: grid; gap: var(--space-3); }
.message-row { display: grid; gap: var(--space-2); padding: var(--space-3) var(--space-4); min-width: 0;
  background: var(--c-tint); border-radius: var(--radius-md); }
.message-row--correction { margin-left: var(--space-4); border-left: 3px solid var(--c-accent); }
/* F-45 (board AA): a pet request or repair entry on Messages, read only: blue-grey edge, chip, "Correct it there". */
.message-row--entry { border-left: 3px solid var(--c-entry-edge); }
.chip--entry { flex: none; background: var(--c-neutral-bg); color: var(--c-neutral); }
.message-row__note { font-size: 0.875rem; font-style: italic; color: var(--c-text-2); }
.message-row p { margin: 0; min-width: 0; }
.message-row__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); }
.message-row__icon { display: inline-flex; color: var(--c-accent); }
.message-row__dir { font-weight: 600; color: var(--c-heading); }
.message-row__head time, .message-row__channel { font-size: 0.8125rem; color: var(--c-text-2); }
.message-row__subject { font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.message-row__people { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); font-size: 0.875rem; overflow-wrap: anywhere; }
.message-row__link { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-1); font-size: 0.875rem;
  overflow-wrap: anywhere; }
.message-row__link > span { display: inline-flex; align-items: center; gap: var(--space-1); flex: none; }
.message-row__link a, .message-row__actions a { display: inline-flex; align-items: center; min-height: var(--tap); }
.message-row__summary { overflow-wrap: anywhere; }
.message-row__added { font-size: 0.75rem; color: var(--c-text-2); }
.message-row__actions { font-size: 0.875rem; }
.message-row__actions .btn { padding: 0 var(--space-3); font-size: 0.875rem; }
.message-earlier .earlier-versions__list { padding: 0 18px var(--space-4); }
.message-row .file-row { background: var(--c-card); }
.repair-entries .message-row { margin: 0; }
.message-form__corrects { margin-bottom: var(--space-3); overflow-wrap: anywhere; }
@media (min-width: 700px) {
  .message-filters { grid-template-columns: repeat(2, auto minmax(0, 1fr)); align-items: center; }
  .message-filters__buttons { grid-column: 1 / -1; }
}

/* Repair alerts (batch 9 Z3) */
/* The one repairs tile takes the full row on phones (its issue list needs the room), a third from 900px. */
.repair-tile .item-tiles__cell { grid-column: 1 / -1; }
@media (min-width: 900px) { .repair-tile .item-tiles__cell { grid-column: auto; } }
.repair-alerts { list-style: none; margin: 0; display: grid; gap: var(--space-1); }
.repair-alert { display: flex; align-items: flex-start; gap: var(--space-2); min-height: var(--tap);
  padding: var(--space-2); border-radius: var(--radius-md); color: var(--c-text); text-decoration: none;
  overflow-wrap: anywhere; }
.repair-alert:hover { background: var(--c-tint); color: var(--c-text); }
.repair-alert > span { display: flex; flex-direction: column; min-width: 0; }
.repair-alert__title { font-weight: 600; color: var(--c-heading); }
.repair-alert:hover .repair-alert__title { text-decoration: underline; }
.repair-alert small { font-size: 0.75rem; color: var(--c-text-2); }
.repair-alert--missed, .repair-alert--missed small { color: var(--c-heading); font-weight: 600; }
.repair-alert > .icon { flex: none; margin-top: 2px; color: var(--c-overdue); }
.tile--wide { grid-column: 1 / -1; }
.repair-overview { gap: var(--space-2); }
.repair-overview__head { display: flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--c-heading); }
.repair-overview__icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px;
  height: 32px; border-radius: var(--radius-md); background: var(--c-accent-bg); color: var(--c-accent); }
.repair-overview__counts { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3); }
.repair-overview__counts .tile__num { color: var(--c-heading); }
.repair-overview__missed { display: inline-flex; align-items: center; gap: var(--space-1); font-size: 0.875rem;
  font-weight: 600; color: var(--c-heading); }
.repair-overview__missed .icon { color: var(--c-overdue); }
.repair-overview__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr);
  border-top: 1px solid var(--c-line-soft); }
.repair-overview__list li { border-bottom: 1px solid var(--c-line-soft); }
.repair-overview__list li:last-child { border-bottom: 0; }
.repair-overview__list a { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0 var(--space-3); min-height: var(--tap); padding: var(--space-1) 0; overflow-wrap: anywhere; }
.repair-overview__address { min-width: 0; }
.repair-overview__line { font-size: 0.8125rem; color: var(--c-text-2); }
.repair-guide summary { gap: var(--space-2); }
.repair-guide__icon { display: inline-flex; color: var(--c-accent); }
.repair-guide p { overflow-wrap: anywhere; }
.repair-guide__sources li { padding: var(--space-1) 0; }
.repair-guide__sources a { display: inline-flex; align-items: center; min-height: var(--tap); overflow-wrap: anywhere; }
.repair-head__record { margin: 0; }
.repair-guide__sources + .hint { margin-top: var(--space-3); }
.repair-targets .hint { margin: var(--space-3) 0 0; }

/* MTD (batch 11a) */
.mtd-tab { min-width: 0; }
.mtd-head__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); }
.mtd-head__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; }
.mtd-period { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2);
  margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--c-line); }
.mtd-period label { font-size: 0.8125rem; font-weight: 600; }
.mtd-head__period { margin: var(--space-3) 0 0; color: var(--c-text-2); font-size: 0.875rem; overflow-wrap: anywhere; }
.mtd-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
.mtd-card { min-width: 0; }
.mtd-card__label { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--c-tile-label); }
.mtd-card__num { font-family: var(--font-mono); font-size: 1.5rem; font-weight: 400; line-height: 1.2;
  overflow-wrap: anywhere; }
.mtd-card__num--income { color: var(--c-num-ok); }
.mtd-card__num--expense { color: var(--c-num-legal); }
.mtd-card__num--finance { color: var(--c-num-due-soon); }
.mtd-card__num--net { color: var(--c-accent); }
.mtd-card__sub { font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
.mtd-card__ytd { font-size: 0.8125rem; color: var(--c-text); padding-top: var(--space-1);
  border-top: 1px solid var(--c-line-soft); }
.mtd-note { margin: 0; overflow-wrap: anywhere; }
.mtd-cats__list { list-style: none; margin: 0; padding: 0; }
.mtd-cats__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-1) var(--space-3);
  align-items: baseline; padding: var(--space-2) 0; border-bottom: 1px solid var(--c-line-soft); font-size: 0.875rem; }
.mtd-cats__row--two { grid-template-columns: minmax(0, 1fr) auto auto; }
.mtd-cats__row--head { font-size: 0.75rem; color: var(--c-text-2); text-transform: uppercase; letter-spacing: 0.06em; }
.mtd-cats__row--total, .mtd-cats__row--income { font-weight: 600; color: var(--c-heading); }
.mtd-cats__row--finance { color: var(--c-text-2); }
.mtd-cats__name { min-width: 0; overflow-wrap: anywhere; }
.mtd-cats__field { display: block; font-family: var(--font-mono); font-size: 0.75rem; color: var(--c-text-2);
  overflow-wrap: break-word; }
.mtd-cats__value { font-family: var(--font-mono); text-align: right; white-space: nowrap; }
.mtd-list { overflow: hidden; }
.mtd-list__title { margin: 0; padding: var(--space-4) var(--space-5) var(--space-2); }
.mtd-rows { list-style: none; margin: 0; padding: 0; }
.mtd-row { border-top: 1px solid var(--c-line-soft); }
.mtd-row:first-child { border-top: 0; }
.mtd-row__link { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3);
  min-height: var(--tap); padding: var(--space-3) var(--space-5); color: var(--c-text); text-decoration: none; }
.mtd-row__link:hover { background: var(--c-tint); color: var(--c-text); }
.mtd-row__link:focus-visible { outline-offset: -2px; }
.mtd-row__date { flex: none; font-size: 0.8125rem; color: var(--c-text-2); min-width: 6.5rem; }
.mtd-row__main { display: flex; flex-direction: column; flex: 1 1 12rem; min-width: 0; }
.mtd-row__category { font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.mtd-row__link:hover .mtd-row__category { text-decoration: underline; }
.mtd-row__desc { font-size: 0.8125rem; color: var(--c-text-2); overflow-wrap: anywhere; }
/* Batch 12 E-24: an edited or not received rent entry outside its tenancy's dates, kept and flagged in words */
.mtd-row__flag { display: inline-flex; align-items: center; gap: var(--space-1); font-size: 0.8125rem; color: var(--c-soon); }
.mtd-row__end { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-left: auto; }
.mtd-row__amount { font-size: 0.9375rem; color: var(--c-heading); white-space: nowrap; }
.mtd-row__receipt { display: inline-flex; color: var(--c-accent); }
.mtd-form__status { margin: 0 0 var(--space-3); display: flex; align-items: center; gap: var(--space-2); }
.mtd-form__fixed { margin: 0; display: flex; flex-direction: column; }
.mtd-form__label { font-size: 0.875rem; font-weight: 600; }
.mtd-form__note { overflow-wrap: anywhere; }
.mtd-form__facts { margin-bottom: var(--space-4); }
.mtd-examples { display: grid; gap: var(--space-1); }
.mtd-examples__item { margin: 0; overflow-wrap: anywhere; }
.mtd-examples__name { font-weight: 600; }
[data-example-for][hidden] { display: none; }
.mtd-card__other { font-size: 0.8125rem; color: var(--c-text); overflow-wrap: anywhere; }
.mtd-card--deadline { border-color: var(--c-line); }
.mtd-card__num--deadline { color: var(--c-heading); }
.mtd-page__title { display: flex; align-items: center; gap: var(--space-2); margin: 0; min-width: 0; }
.mtd-page__title .icon { flex: none; color: var(--c-accent); }
.mtd-props .hint { margin: var(--space-3) 0 0; }
.mtd-page .mtd-head .hint { margin: var(--space-2) 0 0; }
.mtd-table-box { max-width: 100%; overflow-x: auto; border: 1px solid var(--c-line-soft); border-radius: var(--radius-md); }
.mtd-table { width: 100%; min-width: 34rem; border-collapse: collapse; font-size: 0.875rem; }
.mtd-table th, .mtd-table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--c-line-soft);
  text-align: right; white-space: nowrap; }
.mtd-table td { font-family: var(--font-mono); }
.mtd-table thead th { font-size: 0.75rem; color: var(--c-text-2); text-transform: uppercase; letter-spacing: 0.06em;
  font-weight: 600; }
.mtd-table th:first-child { text-align: left; }
.mtd-table tbody th a { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 600; }
.mtd-table tbody tr:last-child th, .mtd-table tbody tr:last-child td { border-bottom: 0; }
.mtd-head__taxpayer { margin: var(--space-2) 0 0; overflow-wrap: anywhere; }
.mtd-taxpayer-warning { margin: 0; overflow-wrap: anywhere; }
.mtd-taxpayer-warning[hidden] { display: none; }
.nav-icon { flex: none; display: inline-flex; }
.archive-receipt__link { display: inline-flex; align-items: center; min-height: var(--tap); font-size: 0.875rem; }
.mtd-row__shared { font-size: 0.8125rem; color: var(--c-text); overflow-wrap: anywhere; }
.mtd-shared__hint { margin: 0; padding: 0 var(--space-5) var(--space-3); }
.mtd-form__shared { margin: 0; overflow-wrap: anywhere; }
.mtd-submit__list { list-style: none; margin: 0; padding: 0; }
.mtd-submit__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2) var(--space-4); padding: var(--space-3) 0; border-top: 1px solid var(--c-line-soft); }
.mtd-submit__row:first-child { border-top: 0; }
.mtd-submit__status { margin: 0; min-width: 0; flex: 1 1 16rem; overflow-wrap: anywhere; }
.mtd-submit__status small { display: block; color: var(--c-text-2); font-size: 0.8125rem; }
.mtd-submit__form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; min-width: 0; }
.mtd-submit__form label { font-size: 0.8125rem; font-weight: 600; }
.mtd-submit__form input[type="date"] { min-height: var(--tap); max-width: 100%; }
.mtd-submit .hint, .mtd-changes .hint { margin: var(--space-3) 0 0; }
.mtd-changes .hint:first-of-type { margin: 0 0 var(--space-3); }
.mtd-changes__table th, .mtd-changes__table td { text-align: left; }
.mtd-changes__table td { font-family: inherit; }
.mtd-changes__table td.date { font-family: var(--font-mono); }
.mtd-sent { flex: 1 1 100%; min-width: 0; }
.mtd-sent__title { margin: var(--space-2) 0 var(--space-1); font-size: 0.9375rem; color: var(--c-heading); overflow-wrap: anywhere; }
.mtd-sent__title small { display: block; font-size: 0.8125rem; font-weight: 400; color: var(--c-text-2); }
.mtd-sent__summary { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); margin: 0 0 var(--space-2); overflow-wrap: anywhere; }
.mtd-sent__blank { flex: 1 1 100%; font-size: 0.8125rem; color: var(--c-text-2); }
.mtd-sent__none { font-family: var(--font-sans); }
.mtd-sent__summary .icon { flex: none; }
.mtd-sent__differs { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--c-soon); font-weight: 600; }
.mtd-sent__table tbody th { font-weight: 400; white-space: normal; min-width: 12rem; }
.mtd-sent__row--total th, .mtd-sent__row--total td { font-weight: 600; color: var(--c-heading); }
.mtd-sent__row--differs td { color: var(--c-soon); }
.mtd-sent__word { font-family: var(--font-sans); font-weight: 600; }
.mtd-sent .hint { margin: var(--space-2) 0 0; }
.mtd-sent__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); margin: var(--space-2) 0 0; }
.mtd-sent__mark { display: inline-flex; align-items: center; min-height: var(--tap); overflow-wrap: anywhere; }
.mtd-sent-choose { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.mtd-sent-choose select { min-height: var(--tap); max-width: 100%; }
.mtd-sent-form__app { margin: 0 0 var(--space-2); }
/* Batch 13 N3 (T7b): All entries list and the Overview "MTD this quarter" tile */
.mtd-entries__tools { display: grid; gap: var(--space-3); padding: 0 var(--space-5) var(--space-3); }
.mtd-entries__filters { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2); margin: 0; }
.mtd-entries__filters label, .mtd-entries__add-form label { font-size: 0.8125rem; font-weight: 600; }
.mtd-entries__filters select, .mtd-entries__filters input, .mtd-entries__add-form select { min-height: var(--tap);
  min-width: 0; max-width: 100%; }
.mtd-entries__buttons { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.mtd-entries__clear { display: inline-flex; align-items: center; min-height: var(--tap); }
.mtd-entries__add { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); padding-top: var(--space-3);
  border-top: 1px solid var(--c-line-soft); }
.mtd-entries__add-form { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; min-width: 0;
  max-width: 100%; }
.mtd-entries__add-form select { flex: 1 1 10rem; }
.mtd-entries__count { margin: 0; padding: 0 var(--space-5) var(--space-2); overflow-wrap: anywhere; }
.mtd-entries__more { margin: 0; padding: var(--space-3) var(--space-5) var(--space-4); border-top: 1px solid var(--c-line-soft); }
.mtd-row__property { font-size: 0.8125rem; font-weight: 600; color: var(--c-text); overflow-wrap: anywhere; }
.mtd-overview { gap: var(--space-2); }
.mtd-overview__head { display: flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--c-heading);
  overflow-wrap: anywhere; }
.mtd-overview__icon { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px;
  height: 32px; border-radius: var(--radius-md); background: var(--c-accent-bg); color: var(--c-accent); }
.mtd-overview__period { font-size: 0.8125rem; color: var(--c-text-2); }
/* Phone: two by two (label above amount), so an amount never breaks inside; 4 across from 480px (F-98). */
.mtd-overview__figures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.mtd-overview__fig { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.mtd-overview__num { font-family: var(--font-mono); font-size: 1rem; font-weight: 700; color: var(--c-heading);
  white-space: nowrap; }
@media (min-width: 480px) {
  .mtd-overview__figures { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-2); }
}
.mtd-overview__due { display: inline-flex; align-items: center; gap: var(--space-1); font-size: 0.875rem;
  color: var(--c-text); overflow-wrap: anywhere; }
.mtd-overview__due .icon { flex: none; color: var(--c-accent); }
/* Batch 15 H2 (F-15): MTD update reminders. Words always say the state ("Due soon", "Overdue", "Not sent"). */
.mtd-overview__link { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; color: var(--c-text);
  text-decoration: none; border-radius: var(--radius-md); }
.mtd-overview__link:hover { color: var(--c-text); }
.mtd-overview__link:hover .mtd-overview__name { color: var(--c-link); }
.mtd-overview--soon { border-color: var(--c-strip-amber); }
.mtd-overview--overdue { border-color: var(--c-strip-red); }
/* Batch 15b J2 (F-9): the Overview "Capital Gains Tax" tile (a .repair-overview list) and the property Sale card. */
.cgt-overview--soon { border-color: var(--c-strip-amber); }
.cgt-overview--overdue { border-color: var(--c-strip-red); }
.sale-card .facts { margin-bottom: var(--space-3); }
.sale-card__cgt { display: grid; gap: var(--space-2); margin: var(--space-3) 0; padding: var(--space-3);
  border: 1px solid var(--c-card-border); border-radius: var(--radius-md); }
.sale-card__cgt--soon { border-color: var(--c-strip-amber); }
.sale-card__cgt--overdue { border-color: var(--c-strip-red); }
.sale-card__cgt p { margin: 0; }
.sale-card__costs { list-style: none; margin: 0 0 var(--space-3); padding: 0; }
.sale-card__costs li { border-bottom: 1px solid var(--c-line-soft); }
.sale-card__costs a { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-1) var(--space-3);
  min-height: var(--tap); align-items: center; padding: var(--space-2) 0; color: var(--c-text); }
.sale-card__amount { font-family: var(--font-mono); font-weight: 700; }
.sale-card__done { display: flex; flex-wrap: wrap; align-items: end; gap: var(--space-2); }
.sale-card__done label { display: grid; gap: var(--space-1); }
.sale-guidance summary { min-height: var(--tap); display: flex; align-items: center; cursor: pointer; font-weight: 600; }
.sale-guidance blockquote { margin: var(--space-2) 0; padding-left: var(--space-3); border-left: 3px solid var(--c-line); }
.mtd-overview__due { margin: 0; flex-wrap: wrap; }
.mtd-overview__due--soon { color: var(--c-soon); font-weight: 600; }
.mtd-overview__due--soon .icon { color: var(--c-soon); }
.mtd-overdue { display: grid; gap: var(--space-2); padding: var(--space-3) 0; border-top: 1px solid var(--c-line-soft);
  min-width: 0; }
.mtd-late .mtd-overdue:first-of-type { border-top: 0; padding-top: 0; }
.mtd-overdue__line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2);
  margin: 0; color: var(--c-heading); overflow-wrap: anywhere; }
.mtd-overdue__line .icon { flex: none; color: var(--c-overdue); }
.mtd-overview__open { margin: 0; }
.mtd-actions { display: grid; gap: var(--space-2); min-width: 0; }
.mtd-actions .mtd-submit__form label { font-size: 0.8125rem; font-weight: 600; }
.mtd-actions .mtd-submit__form input[type="date"] { min-height: var(--tap); width: auto; flex: 0 1 12rem;
  max-width: 100%; min-width: 0; }
.mtd-actions__not-sent .add-entry__body p { margin: 0; overflow-wrap: anywhere; }
.mtd-card--soon { border-color: var(--c-strip-amber); }
.mtd-card__chip { align-self: flex-start; }
@media (min-width: 700px) {
  .mtd-entries__filters { grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; }
  .mtd-entries__buttons { grid-column: 1 / -1; }
  .mtd-overview__num { font-size: 1.25rem; }
}
@media (min-width: 700px) {
  .mtd-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mtd-period { grid-template-columns: auto minmax(0, 10rem) auto minmax(0, 16rem) auto minmax(0, 16rem) auto;
    align-items: center; }
}
@media (min-width: 700px) {
  .mtd-period--taxpayer { grid-template-columns: auto minmax(0, 14rem) auto minmax(0, 8rem) auto minmax(0, 16rem) auto; }
}
@media (min-width: 1100px) {
  .mtd-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .mtd-cards--five { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1400px) {
  .mtd-cards--five { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Overview house picture (batch 12 E-20) */
.house { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3) var(--space-4) var(--space-4); }
.card--tiles > .house { margin-bottom: var(--space-3); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
.house__main { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.house__picture { display: grid; width: 100%; max-width: 640px; min-width: 0; }
.house__picture > svg { grid-area: 1 / 1; display: block; width: 100%; height: auto; overflow: visible; }
.house__outline, .house__stairs, .house__door { fill: none; stroke: var(--c-house-line); stroke-width: 2.5;
  stroke-linejoin: round; }
.house__stairs, .house__door { stroke-width: 2; }
.house__room { fill: var(--c-text-2); font-family: var(--font-sans); font-size: 11px; letter-spacing: 1.2px; }
/* 16 Oct: prefixed with the two places a badge appears (the picture, .house__badges, and the Tenancy and Other rows,
   .house-panel) so a badge keeps its status colour when hovered or tapped (the global a:hover would otherwise turn
   it white, and on a phone a tap leaves it in the hover state). */
.house__badges .house-badge, .house-panel .house-badge { color: var(--c-strip-green); }
.house__badges .house-badge--due-soon, .house-panel .house-badge--due-soon { color: var(--c-strip-amber); }
.house__badges .house-badge--overdue, .house-panel .house-badge--overdue { color: var(--c-strip-red); }
.house__badges .house-badge--good-practice, .house__badges .house-badge--not-in-force,
.house-panel .house-badge--good-practice, .house-panel .house-badge--not-in-force { color: var(--c-strip-grey); }
.house__badges a:focus-visible { outline: none; }
.house-badge__tap { fill: transparent; stroke: none; }
.house-badge__ring { fill: none; stroke: none; stroke-width: 3; }
.house__badges a:focus-visible .house-badge__ring { stroke: var(--c-focus); }
.house-badge__frame { fill: var(--c-card); stroke: currentColor; stroke-width: 2.5; }
.house-badge--good-practice .house-badge__frame { stroke-dasharray: 5 4; }
.house-badge--not-in-force .house-badge__frame { stroke-dasharray: 2 4; }
.house-badge__box { transform-box: fill-box; transform-origin: center; }
.house-badge__count circle { fill: currentColor; }
.house-badge--overdue .house-badge__count circle { fill: var(--c-overdue-bg); }
.house-badge--overdue .house-badge__count text { fill: var(--c-on-overdue); }
.house-badge__count text { fill: var(--c-on-primary); font-family: var(--font-sans); font-size: 12px; font-weight: 700;
  text-anchor: middle; }
.house-dog__ear { stroke: var(--c-card); }
@keyframes house-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.pulse .house-badge__box, .house-panel .pulse { animation: house-pulse 1.6s ease-in-out infinite; }
.house-panel { min-width: 0; }
.house-panel__title { margin: 0 0 var(--space-2); font-size: 0.6875rem; font-weight: 600; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--c-text-2); }
.house-panel__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-3); }
.house-panel .house-badge { display: inline-flex; align-items: center; justify-content: center; width: var(--tap);
  height: var(--tap); background: var(--c-card); border: 2.5px solid currentColor; border-radius: var(--radius-md); }
.house-panel .house-badge--good-practice { border-style: dashed; }
.house-panel .house-badge--not-in-force { border-style: dotted; }
.house-panel__empty { margin: 0; font-size: 0.8125rem; color: var(--c-text-2); }
.house-key { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; flex-wrap: wrap;
  gap: var(--space-2) var(--space-4); font-size: 0.75rem; color: var(--c-text-2); }
.house-key li { display: inline-flex; align-items: center; gap: 6px; }
.house-key__swatch { flex: none; width: 14px; height: 14px; border: 2px solid var(--c-strip-green); border-radius: 4px; }
.house-key__swatch--due-soon { border-color: var(--c-strip-amber); }
.house-key__swatch--overdue { border-color: var(--c-strip-red); }
.house-key__swatch--good-practice { border-color: var(--c-strip-grey); border-style: dashed; }
.house-key__swatch--not-in-force { border-color: var(--c-strip-grey); border-style: dotted; }
.house-attention { margin: 0 0 var(--space-2); font-size: 0.75rem; color: var(--c-text-2); }
.house-all-ok { display: flex; align-items: center; gap: var(--space-2); margin: 0; padding: 0 var(--space-4) var(--space-4);
  font-size: 0.875rem; color: var(--c-ok); }
/* Phones: the house is drawn about half size, so each badge is drawn 1.2 times larger (its 72-unit tap area, about
   36px, stays the same and never overlaps a neighbour's) and the room labels larger; the Tenancy panel is below. */
@media (max-width: 599px) {
  .house__badges .house-badge__box { transform: scale(1.2); }
  .house__room { font-size: 16px; }
}
@media (min-width: 600px) {
  .house__main { flex-direction: row; align-items: flex-start; }
  .house__picture { flex: 1 1 auto; }
  .house-panel--tenancy { flex: none; width: calc(2 * var(--tap) + var(--space-3) + 2 * var(--space-3));
    padding: var(--space-3); border: 1px solid var(--c-card-border); border-radius: var(--radius-xl); }
}
@media (prefers-reduced-motion: reduce) {
  .pulse .house-badge__box, .house-panel .pulse { animation: none; }
}

/* Batch 17 (Pets): the decision deadline in words, amber with 7 days or fewer left and red once passed (the words
   say it too: never colour alone). */
.pet-deadline { display: flex; align-items: flex-start; gap: var(--space-1); margin: 0; font-size: 0.875rem;
  color: var(--c-text-2); }
.pet-deadline > .icon { flex: none; margin-top: 2px; }
.pet-deadline > span { min-width: 0; overflow-wrap: anywhere; }
.pet-deadline--amber, .repair-alert small.pet-deadline--amber { color: var(--c-soon); font-weight: 600; }
.pet-deadline--red, .repair-alert small.pet-deadline--red { color: var(--c-heading); font-weight: 600; }
.pet-deadline--red > .icon { color: var(--c-overdue); }
.pet-row .pet-deadline { font-size: 0.8125rem; }
.pet-entry__details { font-weight: 600; }
.pets-granted__list { margin: var(--space-2) 0 0; }
.pets-granted__list a { display: inline-flex; align-items: center; min-height: var(--tap); overflow-wrap: anywhere; }
.message-row__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.pets-head__note { margin: var(--space-3) 0 0; overflow-wrap: anywhere; }
.pet-caution { display: flex; align-items: flex-start; gap: var(--space-1); }
.pet-caution[hidden] { display: none; }
.pet-caution > .icon { flex: none; margin-top: 2px; }
.pet-caution > span { min-width: 0; overflow-wrap: anywhere; }

/* Batch 18 (Tenancy Timeline, L21): the Timeline tab. The state colours come from the status strip tokens through
   --tl-colour (set per state below); the words beside every marker and row say the state too (never colour alone). */
.tl-marker--ok, .tl-stem--ok, .tl-dot--ok, .tl-row--ok { --tl-colour: var(--c-strip-green); }
.tl-marker--accent, .tl-stem--accent, .tl-dot--accent, .tl-row--accent { --tl-colour: var(--c-accent); }
.tl-marker--due-soon, .tl-stem--due-soon, .tl-dot--due-soon, .tl-row--due-soon { --tl-colour: var(--c-strip-amber); }
.tl-marker--overdue, .tl-stem--overdue, .tl-dot--overdue, .tl-row--overdue { --tl-colour: var(--c-strip-red); }
.tl-marker--neutral, .tl-stem--neutral, .tl-dot--neutral, .tl-row--neutral { --tl-colour: var(--c-strip-grey); }
.timeline-head__note { margin: var(--space-2) 0 0; }
.timeline-head__controls { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3);
  margin-top: var(--space-3); }
.timeline-head__window { margin: var(--space-3) 0 0; }
.tl-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tl-chip { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap); padding: 0 var(--space-3);
  border: 1px solid var(--c-line); border-radius: var(--radius-pill); color: var(--c-text); font-size: 0.875rem;
  text-decoration: none; }
.tl-chip:hover { color: var(--c-heading); background: var(--c-tint); }
.tl-chip[aria-current="true"] { background: var(--c-accent-bg); color: var(--c-heading); font-weight: 700;
  box-shadow: inset 0 0 0 1px var(--c-accent); }
.tl-chip[aria-current="true"] .icon { color: var(--c-accent); }
.tl-chip--zoom { border-radius: var(--radius-md); }
.tl-line { padding: var(--space-3) var(--space-4); }
.tl-svg { display: block; width: 100%; height: auto; overflow: visible; }
.tl-axis { stroke: var(--c-strip-grey); stroke-width: 3; }
.tl-axis--future { stroke-dasharray: 7 6; }
.tl-tick { stroke: var(--c-strip-grey); stroke-width: 2; }
.tl-tick__label { fill: var(--c-text-2); font-family: var(--font-mono); font-size: 12px; text-anchor: middle; }
.tl-today { stroke: var(--c-accent); stroke-width: 1.5; stroke-dasharray: 3 4; }
.tl-today__label { fill: var(--c-accent); font-family: var(--font-sans); font-size: 12px; font-weight: 700; }
.tl-stem { stroke: var(--tl-colour); stroke-width: 1.5; opacity: 0.6; }
.tl-dot { fill: var(--tl-colour); }
.tl-marker { color: var(--tl-colour); }
.tl-marker:focus-visible { outline: none; }
.tl-marker__tap { fill: transparent; stroke: none; }
.tl-marker__ring { fill: none; stroke: none; stroke-width: 3; }
.tl-marker:focus-visible .tl-marker__ring, .tl-marker:hover .tl-marker__ring { stroke: var(--c-focus); }
.tl-marker__frame { fill: var(--c-card); stroke: currentColor; stroke-width: 2.4; }
.tl-marker--upcoming .tl-marker__frame { stroke-dasharray: 4 3; }
.tl-marker--upcoming > g { opacity: 0.8; }
.tl-marker__count circle { fill: var(--c-accent); }
.tl-marker__count text { fill: var(--c-on-primary); font-family: var(--font-sans); font-size: 11px; font-weight: 700;
  text-anchor: middle; }
.tl-marker__date { fill: var(--c-text); font-family: var(--font-mono); font-size: 11px; text-anchor: middle; }
.tl-line__key { margin: var(--space-2) 0 0; }
/* The details panel of a marker: shown while its #tl-<day> is the page's target (works without JavaScript). */
.tl-panel { display: none; }
.tl-panel:target { display: block; box-shadow: inset 0 0 0 1px var(--c-accent); }
.tl-panel__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.tl-panel__head .card__h { margin: 0; }
.tl-panel__close, .tl-panel__open a, .tl-row__title a, .tl-child__title a, .tl-list__order {
  display: inline-flex; align-items: center; min-height: var(--tap); overflow-wrap: anywhere; }
.tl-panel__events { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.tl-panel__event { padding: var(--space-3) 0; border-top: 1px solid var(--c-line-soft); }
.tl-panel__title { margin: 0; font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.tl-panel__kind { margin: 0; font-size: 0.75rem; color: var(--c-text-2); }
.tl-panel__detail, .tl-row__detail { margin: var(--space-1) 0 0; font-size: 0.875rem; color: var(--c-text-2);
  overflow-wrap: anywhere; }
.tl-panel__open { margin: 0; }
.tl-list { padding: 0; }
.tl-list__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-2) var(--space-4); }
.tl-list__head .section-title { margin: 0; }
.tl-rows { list-style: none; margin: 0; padding: 0; }
.tl-row { display: flex; gap: var(--space-3); align-items: flex-start; padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--c-line-soft); }
.tl-row__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 38px;
  height: 38px; border: 2px solid var(--tl-colour); border-radius: var(--radius-md); color: var(--tl-colour); }
.tl-row--upcoming .tl-row__icon { border-style: dashed; opacity: 0.8; }
.tl-row__main { flex: 1; min-width: 0; }
.tl-row__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); margin: 0;
  font-size: 0.75rem; color: var(--c-text-2); }
.tl-row__meta .date { font-size: 0.8125rem; }
.tl-row__title { margin: 0; font-weight: 600; color: var(--c-heading); overflow-wrap: anywhere; }
.tl-today-row { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4);
  color: var(--c-accent); font-size: 0.8125rem; font-weight: 700; }
.tl-today-row::before, .tl-today-row::after { content: ""; flex: 1; border-top: 2px dashed var(--c-accent); }
.tl-notes { list-style: none; margin: var(--space-2) 0 0; padding: 0; font-size: 0.8125rem; color: var(--c-text); }
.tl-notes li { display: flex; align-items: flex-start; gap: var(--space-1); }
.tl-notes .icon { flex: none; margin-top: 2px; color: var(--c-accent); }
.tl-notes span { min-width: 0; overflow-wrap: anywhere; }
.tl-files { margin-top: var(--space-2); }
.tl-children { margin-top: var(--space-2); border: 1px solid var(--c-line); border-radius: var(--radius-md); }
.tl-children > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  min-height: var(--tap); padding: 0 var(--space-3); cursor: pointer; font-size: 0.875rem; list-style: none; }
.tl-children > summary::-webkit-details-marker { display: none; }
.tl-children[open] > summary .icon { transform: rotate(180deg); }
.tl-children__list { list-style: none; margin: 0; padding: 0 var(--space-3) var(--space-2); }
.tl-child { display: flex; flex-direction: column; padding: var(--space-2) 0; border-top: 1px solid var(--c-line-soft);
  font-size: 0.875rem; min-width: 0; }
.tl-child__date { font-size: 0.75rem; color: var(--c-text-2); }
.tl-child__title { font-weight: 600; overflow-wrap: anywhere; }
.tl-child__detail { color: var(--c-text-2); overflow-wrap: anywhere; }
/* Phones and narrow screens (review I-2): below 900px of tab width the line's markers would drop under 44px, so the
   line and panels hide and the list becomes a vertical timeline of dated cards with the Today divider. */
.timeline-tab { container: timeline / inline-size; }
@container timeline (max-width: 899px) {
  .tl-line, .tl-panels { display: none; }
  .tl-list { background: transparent; border: 0; box-shadow: none; }
  .tl-list__head { padding: 0 0 var(--space-2); }
  .tl-rows { position: relative; padding-left: 26px; }
  .tl-rows::before { content: ""; position: absolute; left: 9px; top: 0; bottom: 0; border-left: 3px solid var(--c-strip-grey); }
  .tl-row { position: relative; margin-bottom: var(--space-3); padding: var(--space-3); background: var(--c-card);
    border: 1px solid var(--c-card-border); border-radius: var(--radius-lg); }
  .tl-row::before { content: ""; position: absolute; left: -22px; top: 22px; width: 11px; height: 11px;
    border-radius: 50%; background: var(--tl-colour); }
  .tl-today-row { margin: 0 0 var(--space-3) -26px; padding: var(--space-1) 0; }
}

/* End tenancy tab (batch 20, L22; see the header). Phone first: one column, the route cards side by side from
   700px. Check lines: the state chip (icon + words) above the text on phones, beside it from 700px. */
.end-head__left { margin: var(--space-2) 0 0; color: var(--c-text-2); }
.end-head__note, .notice-form__note { display: flex; gap: var(--space-2); align-items: flex-start; margin: var(--space-3) 0 0; }
.end-head__note .icon, .notice-form__note .icon { flex: none; margin-top: 2px; }
.notice-form__note { margin: 0 0 var(--space-4); }
.route-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); margin-top: var(--space-3); }
.route-card { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4);
  background: var(--c-tint); border: 1px solid var(--c-line); border-radius: var(--radius-lg); }
.route-card p { margin: 0; }
.route-card__title { display: flex; align-items: center; gap: var(--space-2); margin: 0; font-size: 1.05rem; }
.route-card__icon { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px;
  flex: none; border-radius: var(--radius-md); color: var(--c-accent); background: var(--c-accent-bg); }
.route-card__action { margin-top: auto; padding-top: var(--space-2); }
.route-card__action .btn { width: 100%; }
.end-route__facts { margin: var(--space-3) 0; }
.end-route__files { margin: 0 0 var(--space-3); }
.end-route__actions { margin: var(--space-4) 0 0; }
.end-route__withdrawn { margin-top: var(--space-4); }
.end-route__withdrawn-row p { margin: 0 0 var(--space-1); }
.check-lines { list-style: none; margin: 0; padding: 0; }
.check-line { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3) 0;
  border-top: 1px solid var(--c-line-soft); }
.check-line:first-child { border-top: 0; }
.check-line__state { display: inline-flex; align-items: center; gap: var(--space-1); align-self: flex-start; }
.check-line__state .icon { flex: none; }
.check-line__main { min-width: 0; overflow-wrap: anywhere; }
.check-line__label { margin: 0; font-weight: 600; color: var(--c-heading); }
.check-line__evidence { margin: var(--space-1) 0 0; color: var(--c-text); }
.check-line__links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-4); margin: 0;
  color: var(--c-text-2); font-size: 0.9rem; }
.check-line__links:empty { display: none; }
.check-line__links a { display: inline-flex; align-items: center; min-height: var(--tap); }
/* Batch 20 E2: the landlord route (possession.html) and the tick on a check line. */
.check-line__tick { margin: var(--space-2) 0 0; min-height: var(--tap); }
.ground-choice { align-items: flex-start; }
.ground-choice__meta { color: var(--c-text-2); font-size: 0.9rem; }
.ground-other__row { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) 0;
  border-top: 1px solid var(--c-line-soft); }
.ground-other__wording { font-size: 0.9rem; color: var(--c-text-2); }
.court-reasons { margin: var(--space-3) 0 0; }
.possession-ready { margin-top: var(--space-4); padding-top: var(--space-3); border-top: 1px solid var(--c-line); }
.possession-ready .chip { display: inline-flex; align-items: center; gap: var(--space-1); margin: 0 0 var(--space-2); }
.override-current p { margin: 0 0 var(--space-2); }
.notice-form__shorter { padding: var(--space-3); border: 1px solid var(--c-line); border-radius: var(--radius-md); }
.notice-form__checks { min-height: var(--tap); }
/* Batch 20 E3: the Section 8 notice card, What happens next, earlier notices; F-32 the mortgage balance line. */
.possession-notice__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2); }
.possession-notice__head .card__h { display: inline-flex; align-items: center; gap: var(--space-2); margin: 0; }
.possession-notice__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.possession-notice__events { margin: 0 0 var(--space-3); }
.possession-notice .facts { margin: var(--space-3) 0; }
.possession-next .chip { display: inline-flex; align-items: center; gap: var(--space-1); }
.possession-next .plain-list a { display: inline-flex; align-items: center; min-height: var(--tap); }
.possession-earlier { margin-top: var(--space-3); }
.possession-create a, .possession-record-link a { display: inline-flex; align-items: center; min-height: var(--tap); }
.route-card__more { margin: 0; }
.route-card__more a { display: inline-flex; align-items: center; min-height: var(--tap); }
.possession-earlier > .possession-notice { margin-top: var(--space-3); }
.possession-cover__steps { margin: var(--space-3) 0; padding-left: var(--space-5); }
.possession-cover__steps li { margin-bottom: var(--space-2); }
.mortgage-grid__balance { flex-basis: 100%; color: var(--c-text-2); font-size: 0.85rem; }
@media (min-width: 700px) {
  .route-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .check-line { flex-direction: row; align-items: flex-start; gap: var(--space-4); }
  .check-line__state { min-width: 9.5rem; justify-content: flex-start; }
}

/* Batch 21 K1 (F-34, board Q): the reorganised Summary tab. .attention: "Needs attention" chips (a.attention-chip,
   the .chip colours by --overdue --due-soon --good-practice --none --ok, an icon and words, 44px tall, wrapping);
   .tenancy-summary--current: the current tenancy's tenant cards side by side from 900px; .details-tile__docs: the
   agreement and deposit certificate lines (tick + View, or cross + Add it); details.start-group: At Tenancy Start as
   one line once complete ("All N done", Show / Hide); details.finance: "Ownership and finance", a slim card bar
   (.finance__bar, the summary line .finance__line) opening to the Ownership, Mortgage and Selling cards. */
.attention .card__title { margin: 0 0 var(--space-3); }
.attention__chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.attention-chip { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap);
  padding: var(--space-1) var(--space-4); border-radius: var(--radius-pill); font-size: 0.875rem; font-weight: 600;
  line-height: 1.35; text-decoration: none; overflow-wrap: anywhere; }
.attention-chip .icon { flex: none; }
.attention-chip > span { min-width: 0; }
a.attention-chip:hover { text-decoration: underline; }
.attention-chip--overdue { background: var(--c-overdue-bg); color: var(--c-on-overdue); }
.attention-chip--due-soon { background: var(--c-soon-bg); color: var(--c-on-soon); }
.attention-chip--ok { background: var(--c-ok-bg); color: var(--c-on-ok); }
.attention-chip--good-practice, .attention-chip--none { background: var(--c-neutral-bg); color: var(--c-neutral); }
.tenancy-names .date { font-size: 0.8125rem; }
.details-tile__docs { display: flex; flex-wrap: wrap; gap: 0 var(--space-5); margin: var(--space-4) 0 0; padding: var(--space-2) 0 0;
  list-style: none; border-top: 1px solid var(--c-line-soft); }
.details-tile__doc { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); min-height: var(--tap);
  font-weight: 600; overflow-wrap: anywhere; }
.details-tile__doc a { display: inline-flex; align-items: center; min-height: var(--tap); }
.details-tile__doc-icon { display: inline-flex; flex: none; }
.details-tile__doc--on-file .details-tile__doc-icon { color: var(--c-ok); }
.details-tile__doc--missing .details-tile__doc-icon { color: var(--c-overdue); }
.details-tile__docs + .details-tile__links { margin-top: 0; border-top: 0; }
.card details.start-group { margin: var(--space-3) 0; padding: 0 var(--space-4); background: var(--c-card);
  border: 1px solid var(--c-card-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
.start-group > summary { flex-wrap: wrap; min-height: 52px; gap: var(--space-1) var(--space-3); }
.start-group__title { color: var(--c-heading); font-weight: 700; }
.start-group__done { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--c-ok); font-size: 0.875rem; }
.start-group__toggle, .finance__toggle { margin-left: auto; color: var(--c-link); font-size: 0.875rem; }
.start-group > summary > .icon:last-child, .finance > summary > .icon:last-child { margin-left: 0; color: var(--c-link); }
.start-group__hide, .finance__hide { display: none; }
details[open] > summary .start-group__show, details[open] > summary .finance__show { display: none; }
details[open] > summary .start-group__hide, details[open] > summary .finance__hide { display: inline; }
.start-group > .item-tiles { padding: 0 0 var(--space-4); }
details.finance { padding: 0; background: none; border: 0; box-shadow: none; }
.finance__bar { min-height: 52px; padding: var(--space-2) var(--space-4); background: var(--c-card);
  border: 1px solid var(--c-card-border); border-radius: var(--radius-xl); box-shadow: var(--shadow-card); }
.finance__icon { display: inline-flex; flex: none; color: var(--c-accent); }
.finance__text { display: flex; flex-direction: column; min-width: 0; }
.finance__title { color: var(--c-heading); font-weight: 700; }
.finance__line { color: var(--c-text-2); font-size: 0.875rem; font-weight: 400; overflow-wrap: anywhere; }
.finance__body { margin-top: var(--space-4); }
@media (min-width: 900px) {
  .tenancy-summary--current .tenancy-people { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tenancy-summary--current .tenancy-people > details { grid-column: 1 / -1; }
  .finance__text { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 0 var(--space-3); }
}

/* Batch 21 K1 (F-36): the Timeline line's short label under each marker's date (.tl-marker__label, truncated with
   an ellipsis by rental.web.timeline.layout so labels never overlap) and the hover / keyboard-focus text (.tl-tip,
   one per line card, placed by app.js setupTimelineTips; its words are the marker's aria-label). The labels and
   dates get a halo in the card colour so a stem passing behind never cuts through the words. */
.tl-marker__label { fill: var(--c-text-2); font-family: var(--font-sans); font-size: 11px; text-anchor: middle; }
.tl-marker__date, .tl-marker__label { paint-order: stroke; stroke: var(--c-card); stroke-width: 3px; stroke-linejoin: round; }
.tl-line { position: relative; overflow: visible; }  /* a long hover text may run past the card */
.tl-tip { position: absolute; z-index: 5; max-width: min(360px, calc(100% - 16px)); padding: var(--space-2) var(--space-3);
  background: var(--c-tint); color: var(--c-text); border: 1px solid var(--c-accent); border-radius: var(--radius-md);
  box-shadow: var(--shadow-raised); font-size: 0.8125rem; line-height: 1.4; pointer-events: none; overflow-wrap: anywhere; }
.tl-tip[hidden] { display: none; }
.tl-tip p { margin: 0; }
.tl-tip p + p { margin-top: var(--space-1); }
.tl-tip__head { font-weight: 700; color: var(--c-heading); }

/* Batch 21 K2: details.attention-more is the "and N more" fold after the sixth Needs attention chip, opening to the
   rest of the chips in place (K1 follow-up b, final review I-1);
   .rent-guide is the folded "Rent increases and the law" panel inside the Rent card (F-35, the .repair-guide parts),
   .rent-guide__tip its Tip; .rent-card__blocked the line shown instead of "Propose a rent increase" when an ending
   tenancy ends before an increase could start (F-38). Tokens only. */
.attention__more { flex-basis: 100%; }
.attention-more > summary { display: inline-flex; align-items: center; min-height: var(--tap); padding: var(--space-1) var(--space-2);
  font-size: 0.875rem; font-weight: 600; cursor: pointer; }
.attention-more > .attention__chips { margin-top: var(--space-2); }
.rent-guide { margin: var(--space-4) 0 0; border-top: 1px solid var(--c-line-soft); border-bottom: 1px solid var(--c-line-soft); }
.rent-guide details.row-details > summary { padding: 0; }
.rent-guide .row-details__body { padding: 0 0 var(--space-4); }
.rent-guide__tip { padding: var(--space-3) var(--space-4); border-left: 4px solid var(--c-accent); background: var(--c-tint); }
.rent-card__blocked { margin: var(--space-4) 0 0; }

/* Batch 22 R1 (F-43): "Change the rent" (increase or decrease). .rent-choice is the choice page's list of options
   (label.check radios with a hint each; an option that cannot be used is disabled and says why);
   .rent-history__down the amber down arrow before a decrease in the Rent history (its note says "Reduced by
   agreement", so status is never shown by colour alone); .rent-history__files a decrease's files under its row;
   .rent-guide__sub the Increases / Decreases headings in the "Rent changes and the law" panel. Tokens only. */
.rent-choice { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-3) 0 0; border: 0; padding: 0; }
.rent-choice label.check { align-items: flex-start; min-height: var(--tap); }
.rent-choice label.check small { display: block; }
.rent-choice input[disabled] + span { color: var(--c-text-2); }
.rent-history__down { display: inline-flex; vertical-align: middle; margin-right: var(--space-1); color: var(--c-soon); }
.rent-history__files { list-style: none; padding: 0 0 var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); }
.rent-guide__sub { margin: var(--space-3) 0 var(--space-1); font-size: 0.9375rem; color: var(--c-heading); }

/* F-62 (board Z3): the "Section 8 and the law" panel on the Landlord initiated route (.repair-guide / .rent-guide parts).
   __list the bullet lists, __table the grounds table (stacked rows below 700px, no sideways scroll), __chip the
   Mandatory / Discretionary chip (the words say it; the grey neutral pair), __word "Ground" shown on a phone only,
   __hint beside the title while folded (laptop), __foot the "Information, not legal advice" and sources line.
   Tokens only. */
.section8-guide { margin: 0 0 var(--space-4); }
.section8-guide__list { margin: 0; padding-left: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); }
.section8-guide__table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
.section8-guide__table th, .section8-guide__table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--c-line-soft);
  text-align: left; vertical-align: top; overflow-wrap: anywhere; }
.section8-guide__table thead th { font-size: 0.75rem; font-weight: 600; color: var(--c-text-2); border-bottom: 1px solid var(--c-line); }
.section8-guide__table tbody th { font-weight: 700; color: var(--c-heading); white-space: nowrap; }
.section8-guide__foot { margin-top: var(--space-4); }
.section8-guide__chip { background: var(--c-neutral-bg); color: var(--c-neutral); }
.section8-guide__chip--mandatory { color: var(--c-text); }
.section8-guide__word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.section8-guide details[open] .section8-guide__hint { display: none; }
@media (max-width: 699px) {
  .section8-guide__word { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
  .section8-guide__hint { display: none; }
  .section8-guide__table td:empty { display: none; }
  .section8-guide__table, .section8-guide__table tbody, .section8-guide__table tr,
  .section8-guide__table th, .section8-guide__table td { display: block; width: 100%; }
  .section8-guide__table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .section8-guide__table tr { padding: var(--space-2) 0; border-bottom: 1px solid var(--c-line-soft); }
  .section8-guide__table th, .section8-guide__table td { padding: var(--space-1) 0; border: 0; }
  .section8-guide__table td[data-label]::before { content: attr(data-label); display: block; font-size: 0.75rem; color: var(--c-text-2); }
}

/* Batch 22 R2 (Contacts, L23, board S): the Contacts list (.contacts-head with the one lime button, the trade chips
   reuse .tl-chips, .contact-list of .contact-card cards: name with the amber star when preferred (the hidden text
   says "preferred", so never by colour alone), trade, registration, tap to call and email links, notes), the contact
   page (.contact-detail, .contact-links-list, .contact-actions) and .contact-links (contact page link and "Call"
   beside a contact picked on a repair update or a record). Tokens only; every link and button is 44px. */
.contacts-head { align-items: center; }
.contact-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
@media (min-width: 900px) { .contact-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.contact-card { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.contact-card--archived { opacity: 0.85; border-style: dashed; }
.contact-card__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.contact-card__name { display: inline-flex; align-items: center; min-height: var(--tap); color: var(--c-heading);
  font-weight: 700; font-size: 1rem; overflow-wrap: anywhere; }
.contact-card__trade { margin-left: auto; color: var(--c-text-2); font-size: 0.8125rem; }
.contact-card__meta { margin: 0; color: var(--c-text-2); font-size: 0.875rem; overflow-wrap: anywhere; }
.contact-card__links { display: flex; flex-wrap: wrap; gap: 0 var(--space-4); margin: 0; }
.contact-card__links a, .contact-links-list a, .contact-links a { display: inline-flex; align-items: center;
  gap: var(--space-2); min-height: var(--tap); overflow-wrap: anywhere; }
.contact-card__notes { margin: 0; color: var(--c-text); font-size: 0.875rem; white-space: pre-line; overflow-wrap: anywhere; }
.contact-star { display: inline-flex; color: var(--c-strip-amber); }
.contact-star .icon { fill: currentColor; }
.contacts-archived { margin: 0; }
.contacts-archived a { display: inline-flex; align-items: center; min-height: var(--tap); }
/* Batch 22 R3 (R2 review m-6, m-7): Restore on an archived contact card; "Add your trades in Contacts to pick them
   here" under a Who or Done by field when there are no active contacts (the link is 44px tall). */
.contact-card__restore { margin: var(--space-1) 0 0; }
/* F-80 live fix (18 Oct): the contact form's category blocks are .stack (display: grid), which beat the hidden
   attribute, so the gas, electrician, agent address and property blocks never hid. */
[data-contact-for][hidden] { display: none; }
.contacts-hint a { display: inline-flex; align-items: center; min-height: var(--tap); }
.contact-detail__name { display: flex; align-items: center; gap: var(--space-2); margin: 0; overflow-wrap: anywhere; }
.contact-detail__meta { margin: var(--space-1) 0 var(--space-3); color: var(--c-text-2); overflow-wrap: anywhere; }
.contact-links-list { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; flex-wrap: wrap; gap: 0 var(--space-5); }
.contact-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-4); }
.contact-actions form { margin: 0; }
.contact-jobs__note { font-weight: 400; font-size: 0.8125rem; color: var(--c-text-2); }
.contact-jobs .list-row__title .icon { vertical-align: middle; color: var(--c-accent); }
.contact-links { display: inline-flex; flex-wrap: wrap; gap: 0 var(--space-3); margin-left: var(--space-2); }
.repair-entry__contact { margin: 0; font-size: 0.875rem; }
.repair-entry__contact .contact-links { margin-left: 0; }

/* Batch 23 S1 (F-47, board U): the Overview property list. .prop-list-head is the "Properties" heading with the
   "Show all issues · Hide all issues" links; .prop-list holds the cards, one per row on phones and tablets; from
   1100px closed cards sit two per row (a smaller house picture) and an open card spans the full width
   (by :has() on the open fold; .prop-card--open, set by the server and kept by app.js, is a marker only).
   details.prop-issues holds the colour key, "Needs attention:" and the tiles; its summary .prop-issues__toggle is the
   "Show issues" / "Hide issues" button at the top right of the card (the words follow [open], so it works without
   JS; on narrow phones the word "issues" is hidden visually but still read out). .prop-card__chips sit under the
   address and say what is hidden. Tokens only. */
.prop-list-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--space-3); }
.prop-list-head__title { margin: 0; font-size: 1.25rem; }
.prop-list-head__links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-2); margin: 0;
  color: var(--c-text-2); font-weight: 600; font-size: 0.875rem; }
.prop-list-head__links a { display: inline-flex; align-items: center; min-height: var(--tap); }
.prop-list { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.prop-card { position: relative; overflow: visible; }
.prop-card .card__title { padding-right: calc(8.75rem + var(--space-2)); }
.prop-card .card__heading { gap: var(--space-2); }
.prop-card .prop-card__chips { justify-content: flex-start; }
.prop-card .prop-card__chips .chip { white-space: normal; }
details.prop-issues { padding: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
details.prop-issues > summary.prop-issues__toggle { position: absolute; top: var(--space-3); right: var(--space-3); z-index: 2;
  min-height: var(--tap); padding: 0 var(--space-3); gap: var(--space-2); background: var(--c-card);
  border: 1px solid var(--c-line); border-radius: var(--radius-md); color: var(--c-link); font-size: 0.875rem;
  white-space: nowrap; cursor: pointer; list-style: none; }
details.prop-issues > summary.prop-issues__toggle:hover { border-color: var(--c-accent); color: var(--c-link-hover); }
details.prop-issues > summary.prop-issues__toggle > .icon:last-child { margin-left: 0; transition: none; }
details.prop-issues > summary::marker { content: ""; }
.prop-issues__hide, details.prop-issues[open] .prop-issues__show { display: none; }
details.prop-issues[open] .prop-issues__hide { display: inline; }
.prop-card--compact details.prop-issues > .house-key, .prop-card--compact details.prop-issues > .house-attention { padding: 0 var(--space-4); }
.prop-card.card--tiles details.prop-issues[open] > .house-key { margin-top: 0; }
/* S1 review I-2: an all-OK card's list of every item, inside its card */
.prop-card--compact details.prop-issues > .item-tiles--all { padding: 0 var(--space-4) var(--space-4); }
@media (max-width: 479px) {
  .prop-card .card__title { padding-right: calc(5.5rem + var(--space-2)); }
  .prop-issues__word { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
}
@media (min-width: 900px) {
  .prop-list { gap: var(--space-6) var(--space-5); }
}
@media (min-width: 1100px) {
  .prop-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* S1 review M-1: the span follows the fold itself (:has), so a card closed without JS goes back to half width */
  .prop-card:has(> details.prop-issues[open]) { grid-column: 1 / -1; }
  /* a half-width card puts the Tenancy panel under the house, so the picture keeps its width */
  .prop-card:not(:has(> details.prop-issues[open])) .house__main { flex-direction: column; }
  .prop-card:not(:has(> details.prop-issues[open])) .house-panel--tenancy { width: auto; }
}

/* Batch 23 S1 (F-48, board V): .overview-wide is an Overview wide row (F-100: Coming up on its own under the counts;
   Repairs and Pet requests after MTD), its tiles side by side when there is room, each at least 300px; .coming-up is the "Coming up" tile (a
   .repair-overview list with a lime border): .coming-up__window "next 90 days", .coming-up__icon per line (--ok green
   rent changes, --soon orange tenancy ends and notices to serve; the words say what it is). Tokens only. */
.overview-wide { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3); }
.overview-wide > .tile { flex: 1 1 300px; min-width: 0; }
.overview-wide > .coming-up { flex-grow: 1.4; }
.coming-up__window { margin-left: auto; font-size: 0.8125rem; font-weight: 400; color: var(--c-text-2); }
.coming-up__icon { display: inline-flex; vertical-align: middle; margin-right: var(--space-2); }
.coming-up__icon--ok { color: var(--c-strip-green); }
.coming-up__icon--soon { color: var(--c-strip-amber); }
@media (min-width: 900px) { .overview-wide { gap: var(--space-4); } }
/* F-100: the Overview "Landlord register" tile on its own row below the Ask TInA bar, before the properties. */
.overview-register { margin: var(--space-5) 0; }

/* Batch 23 S1 (F-51): the house badges' hover and keyboard-focus label (.house-tip, made by app.js setupHouseTips):
   the Timeline marker label style (.tl-tip, F-36) with the badge's aria-label as its words, above the badge (below it
   when there is no room above on the screen), kept inside the house box; absolutely placed, so nothing moves. */
.house { position: relative; }
.house-tip { margin: 0; max-width: min(320px, calc(100% - 8px)); }

/* Batch 23 S2 (F-50): the file card of an item met by a file (record.html, _macros file_item_card): the slot's name
   with the "On file" or "Not on file yet" chip, .file-item__name (icon, file name, "Added <date>"), View and
   Download (.btn-pair), the "Replace with a newer version" disclosure and the "All tenancy documents" link. */
.file-item__file { display: grid; gap: var(--space-3); margin-top: var(--space-3); }
.file-item__name { display: flex; align-items: center; gap: 10px; margin: 0; padding: var(--space-3);
  border-radius: var(--radius-md); background: var(--c-tint); font-size: 0.9375rem; }
.file-item__name .icon { flex: none; color: var(--c-accent); }
.file-item__name span { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.file-item__name small { display: block; color: var(--c-text-2); }
.file-item__actions { margin: 0; }
.file-item__actions .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--tap); }
.file-item__replace { margin-top: var(--space-3); }
.file-item__add { margin-top: var(--space-3); }
.file-item__foot { margin: var(--space-3) 0 0; }
.file-item__foot a { display: inline-flex; align-items: center; min-height: var(--tap); }

/* Batch 23 S2 (F-52): the Evidence packs tab (.evidence-tab: the builder card, then the packs made before, the
   batch 19 .pack-list rows) and the small "Make an evidence pack" shortcut links (.pack-shortcut: folder-with-tick
   icon and words, 44px tall) on the Repairs issue, pet request, End tenancy and Rent screens; .evidence-line is the
   one line on the Summary tab that links to the tab. */
.pack-shortcuts { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-4); margin: 0; }
.pack-shortcut { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); font-size: 0.875rem; }
.pack-shortcut .icon { flex: none; color: var(--c-accent); }
.evidence-line { margin: var(--space-3) 0 0; }
.evidence-line a { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); }
.evidence-line .icon { flex: none; color: var(--c-accent); }
.evidence-tab .pack-list { margin: 0; padding: 0; }

/* Ask Tina stage 4 (PRD T15): the allowance bar (.tina-bar, macro allowance_bar in _tina.html): a track with a fill
   set by --fill (0 to 100%) and the sentence under it, which always says the state (the colour only repeats it):
   --green (--c-ok) below 75% of the monthly limit, --amber (--c-soon) from 75%, --red (--c-overdue) at the limit.
   .tina-privacy is the one-line privacy note (macro privacy_line). Settings > Tina is .tina-settings. */
.tina-bar { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; }
.tina-bar__track { display: block; height: 10px; border-radius: var(--radius-pill); background: var(--c-line); overflow: hidden; }
.tina-bar__fill { display: block; width: var(--fill, 0%); height: 100%; border-radius: var(--radius-pill); background: var(--c-ok); }
.tina-bar--amber .tina-bar__fill { background: var(--c-soon); }
.tina-bar--red .tina-bar__fill { background: var(--c-overdue); }
.tina-bar__words { margin: 0; font-size: 0.875rem; overflow-wrap: anywhere; }
.tina-bar--red .tina-bar__words { font-weight: 600; }
.tina-privacy { margin: 0; }
.tina-settings { display: flex; flex-direction: column; gap: var(--space-3); }
.tina-settings > p { margin: 0; }
.tina-settings__cap { display: inline-flex; align-items: center; gap: var(--space-2); }
.tina-settings__cap input { max-width: 6rem; }
.tina-settings__link { display: inline-flex; align-items: center; min-height: var(--tap); }
/* F-95: the Ask TInA link in the Final month's rent card's question hint is 44px tall. */
/* Browser check (final review): an inline link in the hint; vertical padding on an inline box gives the 44px tap
   area without stretching its line (inline-flex split the sentence into uneven lines). */
.final-rent-settings__ask { display: inline; padding-block: calc((var(--tap) - 1em) / 2); }

/* Ask Tina stage 4, Task 4 (boards T and Y): the Ask Tina page (.tina-page; .page-subtitle the muted line under the
   heading), the chat (.tina-chat, one column): .tina-top (.tina-chip "Asking about", details.tina-change with the
   picker, History and New chat), article.tina-turn (focusable, so a screen reader starts at the new answer) with the
   question bubble .tina-q and the answer card .tina-answer (.tina-part headed parts, a.tina-cite citation chips: 24px,
   the inline-target exception, each also a 44px row in ol.tina-sources; .tina-choices "Which property?" and "Show
   these steps for:" pills; the disclaimer last; .tina-answer__cost under the card), the question box .tina-ask (the
   bar beside the box from 700px, below it on phones), .tina-not-set-up, History (.tina-history rows,
   details.tina-rename) and the delete step (.tina-delete). Lime is only on the Ask button and links. */
.page-subtitle { margin: calc(-1 * var(--space-2)) 0 var(--space-4); color: var(--c-text-2); }
.tina-page { max-width: 860px; }
.tina-chat { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.tina-top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.tina-chip { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); min-height: var(--tap);
  margin: 0; padding: var(--space-1) var(--space-3); border: 1px solid var(--c-field-border); border-radius: var(--radius-lg);
  color: var(--c-heading); font-weight: 600; overflow-wrap: anywhere; }
.tina-chip__k { color: var(--c-text-2); font-weight: 400; }
details.tina-change, details.tina-rename, .tina-sources details { padding: 0; background: none; border: 0; box-shadow: none;
  border-radius: 0; }
details.tina-change > summary, details.tina-rename > summary { display: inline-flex; padding: 0 var(--space-2);
  color: var(--c-link); text-decoration: underline; }
details.tina-change[open] { flex-basis: 100%; order: 3; }
.tina-change__body { display: grid; gap: var(--space-2); padding-top: var(--space-2); max-width: 520px; }
.tina-change__body .hint { margin-top: 0; }
.tina-top__links { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0 0 0 auto; }
.tina-turns { display: flex; flex-direction: column; gap: var(--space-6); }
.tina-turn { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.tina-turn:focus { outline: none; }
.tina-turn:focus-visible { outline: 2px solid var(--c-focus); outline-offset: 4px; border-radius: var(--radius-lg); }
.tina-q { align-self: flex-end; max-width: 85%; margin: 0; padding: var(--space-3) var(--space-4); font-size: 1rem;
  font-weight: 600; line-height: 1.5; color: var(--c-heading); background: var(--c-line);
  border-radius: var(--radius-xl) var(--radius-xl) var(--radius-sm) var(--radius-xl); overflow-wrap: anywhere; }
.tina-answer { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; padding: var(--space-4);
  background: var(--c-card); border: 1px solid var(--c-card-border); overflow-wrap: anywhere;
  border-radius: var(--radius-xl) var(--radius-xl) var(--radius-xl) var(--radius-sm); }
.tina-answer p { margin: 0; }
.tina-part { display: flex; flex-direction: column; gap: var(--space-2); }
.tina-part__h { margin: 0; font-size: 0.8125rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--c-heading); }
.tina-cite { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; min-height: 24px;
  padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--c-line); color: var(--c-link);
  font-family: var(--font-mono); font-size: 0.75rem; line-height: 1; text-decoration: none; vertical-align: middle; }
.tina-cite:hover { color: var(--c-link-hover); }
.tina-steps { margin: 0; padding-left: var(--space-5); }
.tina-steps li + li { margin-top: var(--space-1); }
.tina-answer__caveat { color: var(--c-text); }
.tina-answer .hint { margin-top: 0; }
.tina-choices { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.tina-choices__h { flex-basis: 100%; font-weight: 600; }
.tina-again { margin: 0; }
.tina-pill { border-radius: var(--radius-pill); }
.tina-sources-box { display: flex; flex-direction: column; gap: var(--space-2); }
.tina-sources { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--c-line); }
.tina-sources > li { border-bottom: 1px solid var(--c-line); }
.tina-sources li > details > summary { min-height: var(--tap); padding: var(--space-1) 0; font-weight: 400; }
.tina-sources__n { display: inline-flex; flex: none; align-items: center; justify-content: center; min-width: 24px;
  min-height: 24px; border-radius: var(--radius-sm); background: var(--c-line); font-family: var(--font-mono); font-size: 0.75rem; }
.tina-sources__label { min-width: 0; overflow-wrap: anywhere; }
.tina-sources__title { color: var(--c-text-2); font-size: 0.875rem; }
.tina-sources__body { display: flex; flex-direction: column; gap: var(--space-2); padding: 0 0 var(--space-3); }
.tina-sources__text { padding: var(--space-3); border-radius: var(--radius-md); background: var(--c-field-bg); font-size: 0.875rem;
  white-space: pre-wrap; }
.tina-sources__link a { display: inline-flex; align-items: center; min-height: var(--tap); }
.tina-answer__disclaimer { color: var(--c-text-2); font-size: 0.875rem; }
.tina-answer__cost { margin: 0; }
.tina-answer--working .tina-working { color: var(--c-heading); }
.tina-ask { display: flex; flex-direction: column; gap: var(--space-3); }
.tina-ask__row { display: flex; align-items: stretch; gap: var(--space-2); }
.tina-ask__row textarea { flex: 1; min-width: 0; resize: vertical; }
.tina-ask__btn { flex: none; }
.tina-ask .hint { margin-top: 0; }
@media (min-width: 700px) {
  .tina-ask { display: grid; grid-template-columns: minmax(0, 1fr) minmax(200px, 280px); align-items: center;
    gap: var(--space-3) var(--space-4); }
  .tina-ask .tina-bar { grid-column: 2; grid-row: 1; }
  .tina-ask .tina-privacy { grid-column: 1 / -1; }
}
.tina-not-set-up { margin: 0; padding: var(--space-4); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); font-weight: 600; }
.tina-not-set-up p { margin: 0; }
.tina-not-set-up .hint { margin-top: var(--space-1); font-weight: 400; }
.tina-history { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--c-line); }
.tina-history__row { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-2) 0; border-bottom: 1px solid var(--c-line); }
.tina-history__title { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 600; overflow-wrap: anywhere; }
.tina-history__meta { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); margin: 0; color: var(--c-text-2);
  font-size: 0.875rem; }
.tina-history__actions { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 var(--space-4); }
.tina-history__delete { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--space-2); font-weight: 600; }
details.tina-rename[open] { flex-basis: 100%; }
.tina-rename__form { display: grid; gap: var(--space-2); max-width: 420px; padding: var(--space-2); }
.tina-delete__title { overflow-wrap: anywhere; }

/* F-58 (board Y): on the Ask Tina page, one row of property buttons above the question box (.tina-props: the muted
   "Asking about:" then form.tina-prop GET forms, each a 44px .tina-prop__btn; wraps on phones). The pressed one
   (aria-pressed="true") is an outlined lime chip: lime border and words, no fill, so the Ask button stays the one lime
   primary. While Tina works: .tina-working-row with .tina-spinner (a turning ring, lime on the line colour) and
   .tina-working__time (the elapsed counter). Under prefers-reduced-motion the ring is replaced by the still clock
   icon (.tina-working__still) and the counter only. */
.tina-props { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0; }
.tina-props__k { color: var(--c-text-2); font-size: 0.875rem; }
.tina-prop { margin: 0; min-width: 0; max-width: 100%; }
.tina-prop__btn { min-height: var(--tap); max-width: 100%; padding: 0 var(--space-3); border-radius: var(--radius-pill);
  border-color: var(--c-field-border); color: var(--c-text); font-weight: 400; font-size: 0.875rem;
  overflow-wrap: anywhere; text-align: center; }
.tina-prop__btn[aria-pressed="true"] { border-color: var(--c-accent); color: var(--c-accent); background: transparent;
  font-weight: 600; }
.tina-prop__btn[aria-pressed="true"]:hover { color: var(--c-accent); background: var(--c-tint); }
.tina-working-row { display: flex; align-items: flex-start; gap: var(--space-3); }
.tina-working__words { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.tina-working__time { color: var(--c-text-2); font-size: 0.875rem; font-variant-numeric: tabular-nums; }
.tina-spinner { flex: none; width: 18px; height: 18px; margin-top: 2px; border-radius: 50%; border: 3px solid var(--c-line);
  border-top-color: var(--c-accent); animation: tina-spin 0.9s linear infinite; }
.tina-working__still { display: none; flex: none; margin-top: 2px; color: var(--c-accent); }
@keyframes tina-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .tina-spinner { display: none; }
  .tina-working__still { display: inline-flex; }
}

/* Ask Tina stage 4, Task 5 (board T): the property Ask Tina tab (.tina-tab) and the "Ask Tina about this" links
   (.tina-about: the ask icon and words, 44px tall, as the evidence pack shortcuts). Lime is only on Ask and the
   links. */
.tina-tab { min-width: 0; max-width: 860px; }
.tina-about-line { margin: 0; }
.tina-about { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); font-size: 0.875rem; }
.tina-about .icon { flex: none; color: var(--c-accent); }

/* F-60 (board Z2): Ask Tina on the Overview as one slim bar after the status tiles (.tina-overview, a plain border:
   it is not a status, F-55). .tina-overview__row is one grid row from 700px (the name, the one-line 44px question
   box, the lime Ask); on a phone the name takes its own line and the box and Ask share the next. .tina-overview__hint
   is the one quiet line under it (what Tina reads, the allowance left, "Examples and history"). */
.tina-overview { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; margin: var(--space-5) 0;
  padding: var(--space-3) var(--space-4); background: var(--c-card); border: 1px solid var(--c-card-border);
  border-radius: var(--radius-xl); }
.tina-overview__ask { display: flex; flex-direction: column; gap: var(--space-2); margin: 0; min-width: 0; }
.tina-overview__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: var(--space-2) var(--space-3); min-width: 0; }
.tina-overview__name { display: inline-flex; align-items: center; gap: var(--space-2); grid-column: 1 / -1; }
.tina-overview__name h2 { margin: 0; font-size: 1rem; white-space: nowrap; }
.tina-overview__icon { display: inline-flex; flex: none; color: var(--c-accent); }
.tina-overview__row input { min-width: 0; min-height: var(--tap); }
.tina-overview__hint { margin: 0; font-size: 0.8125rem; overflow-wrap: anywhere; }
@media (min-width: 700px) {
  .tina-overview__row { grid-template-columns: auto minmax(0, 1fr) auto; }
  .tina-overview__name { grid-column: auto; }
  .tina-overview__hint { padding-left: calc(22px + var(--space-2)); }
}

/* Ask Tina stage 4, Task 6 (PRD T8; board Y): Tina's sources (.tina-src): cards for About Tina, what Tina reads
   (.tina-reads rows: name, what, when; three columns from 700px, stacked on phones), the law library (.tina-lib rows,
   each title a 44px link, the "Re-check due" chip with its words), your documents and the licence. The Ask Tina
   page footer link is .tina-page__foot. */
.tina-src { display: flex; flex-direction: column; gap: var(--space-4); }
.tina-src > h1, .tina-src > .crumbs { margin-bottom: 0; }
.tina-src__card { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; overflow-wrap: anywhere; }
.tina-src__card > p, .tina-src__card .card__h { margin: 0; }
.tina-src__card .hint { margin-top: 0; }
.tina-src__icon { display: inline-flex; flex: none; margin-right: var(--space-2); color: var(--c-accent); vertical-align: middle; }
.tina-reads, .tina-lib { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.tina-reads__row { display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3) 0; border-top: 1px solid var(--c-line); }
.tina-reads__name { color: var(--c-heading); }
.tina-reads__what { color: var(--c-text-2); }
.tina-reads__when { color: var(--c-ok); font-size: 0.875rem; }
@media (min-width: 700px) {
  .tina-reads__row { display: grid; grid-template-columns: 160px minmax(0, 1fr) 190px; gap: var(--space-3); }
}
.tina-lib__h { margin: var(--space-2) 0 0; font-size: 1rem; }
.tina-lib__row { display: flex; flex-direction: column; padding: var(--space-1) 0 var(--space-2); border-top: 1px solid var(--c-line); }
.tina-lib__row > a { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 600; }
.tina-lib__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); margin: 0;
  color: var(--c-text-2); font-size: 0.875rem; }
.tina-page__foot { margin: var(--space-4) 0 0; }
.tina-page__foot a { display: inline-flex; align-items: center; min-height: var(--tap); }

/* F-55 (Tina stage 4 release; boards X and X2): a tile or card border only shows status. Templates set data-border
   (rental.web.borders): red overdue or missing, orange due soon, gp blue-grey good practice outstanding, green OK or
   positive, plain no status. 2px in the --c-border-* tokens; the chips, numbers and words always say the same thing
   (never colour alone). Overview: the count tiles (plain at 0), OK, Coming up, MTD, Repairs, Pet requests, Capital
   Gains Tax, the property cards (worst issue; a card with tiles becomes a framed box) and the Ask Tina box (plain).
   Property pages: Needs attention, Tenancy details, At Tenancy Start (.start-box frames the tiles until complete),
   Ownership and finance, the Rent card, open repair and pet request rows and the move-out items. Lime stays for
   buttons and links: a plain tile link keeps its lime hover, a status tile keeps its colour on hover. */
[data-border="plain"] { --status-border: var(--c-border-plain); }
[data-border="red"] { --status-border: var(--c-border-red); }
[data-border="orange"] { --status-border: var(--c-border-orange); }
[data-border="gp"] { --status-border: var(--c-border-gp); }
[data-border="green"] { --status-border: var(--c-border-green); }
.tile[data-border], .card[data-border], .tina-overview[data-border], .card--tiles > .card__body[data-border],
.card details.start-group[data-border], .start-box[data-border], .finance__bar[data-border],
.repair-rows > .repair-row[data-border]:not([data-border="plain"]) {
  border: var(--border-status) solid var(--status-border, var(--c-border-plain)); }
a.tile[data-border]:hover { border-color: var(--status-border, var(--c-border-plain)); }
a.tile[data-border="plain"]:hover { border-color: var(--c-accent); }
.card.card--tiles[data-border] { padding: var(--space-3); border-radius: var(--radius-xl); }
.prop-card.card--tiles[data-border] > details.prop-issues > summary.prop-issues__toggle {
  top: calc(var(--space-3) * 2); right: calc(var(--space-3) * 2); }
.start-box { margin: var(--space-3) 0; padding: 0 var(--space-3) var(--space-3); border-radius: var(--radius-xl); }
.start-box > .item-tiles { padding: 0; }
.repair-rows > .repair-row[data-border]:not([data-border="plain"]) { margin: var(--space-2) var(--space-3);
  border-radius: var(--radius-md); overflow: hidden; }

/* F-53: Settings > Legal landlords: the Companies House personal code (mono, wraps on phones) and its Copy button
   (secondary, 44px; shown by app.js setupCopyValue). Private: on this page only. */
.ll-card__code { font-family: var(--font-mono); overflow-wrap: anywhere; }
.ll-card__copy { margin-left: var(--space-2); vertical-align: middle; }
.ll-card__copy[hidden] { display: none; }  /* L30 final review: .btn's display would show it without JS */

/* L25 S1: the Rent account card on the Rent tab (board AC1). Tokens only; the border comes from data-border. */
.rent-account__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--space-2) var(--space-3); }
.rent-account__head .card__title { margin: 0; }
.rent-account__since { color: var(--c-text-2); font-size: 0.8125rem; }
.rent-account__balance { margin: var(--space-3) 0 var(--space-1); font-size: 1.75rem; font-weight: 800;
  line-height: 1.2; color: var(--c-text); }
.rent-account__balance--due-soon { color: var(--c-soon); }
/* --overdue keeps white text (red is never small text on navy): the red border and the red Ground 8 chip say it. */
.rent-account__ground8 { margin: 0 0 var(--space-3); color: var(--c-text); }
.rent-account__problems { margin: 0 0 var(--space-3); }
.rent-account__problem { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-2) 0; border-top: 1px solid var(--c-line); }
.rent-account__labels { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.rent-account__open { display: inline-flex; align-items: center; min-height: var(--tap); }
.rent-account__all { margin: 0 0 var(--space-3); }
.rent-account__all > summary { min-height: var(--tap); }
.rent-account__note { margin: 0; }
/* end L25 S1 */

/* L25 S2 Task 8 (board AC4): the Rent arrears card on the Section 8 page and the "This tenancy" box. Tokens only;
   no red text (the warning is white text on the tint with an orange edge). */
.s8-arrears__note { margin: 0; padding: var(--space-3) var(--space-4); border-left: 4px solid var(--c-border-orange);
  border-radius: var(--radius-md); background: var(--c-tint); color: var(--c-text); }
.s8-arrears__hint { margin: 0; padding: var(--space-3) var(--space-4); border-left: 4px solid var(--c-border-gp);
  border-radius: var(--radius-md); background: var(--c-tint); color: var(--c-text-2); }
.section8-guide__tenancy { margin: var(--space-3) 0 0; padding: var(--space-3) var(--space-4); border: 1px solid var(--c-line);
  border-radius: var(--radius-md); background: var(--c-tint); }
.section8-guide__tenancy p { margin: var(--space-1) 0 0; }
.section8-guide__tenancy-title { margin: 0; font-size: 0.9375rem; color: var(--c-heading); }
.section8-guide__tenancy-link { display: inline-flex; align-items: center; min-height: var(--tap); }
/* end L25 S2 Task 8 */

/* L30 Register tab (Task 8, board AD delivery 1): the Preview banner (amber border, white text on the card), the
   registration card and the entry grid. A row is question, answer, Copy on a laptop; under 640px one card per
   question with the Copy button full width. Copy and Show buttons are 44px. */
.register-banner { border: var(--border-status) solid var(--c-border-orange); }
.register-banner__title { margin: 0; font-size: 1rem; color: var(--c-heading); }
.register-banner__text { margin: var(--space-1) 0 0; color: var(--c-text); }
.register-status__line, .register-status__number, .register-status__fee, .register-status__service { margin: 0 0 var(--space-2); }
.register-status__number { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.register-status__ref { font-weight: 700; color: var(--c-heading); }
.register-status__service a { display: inline-flex; align-items: center; min-height: var(--tap); }
.register-record { display: grid; gap: var(--space-2); max-width: 28rem; margin-top: var(--space-3); }
.register-entry__head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--space-2); }
.register-entry__missing { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: var(--space-2) 0 0; }
.register-section { margin: var(--space-5) 0 var(--space-2); font-size: 0.9375rem; color: var(--c-heading); }
.register-section__note { margin: 0 0 var(--space-2); }
/* F-83: the certificate copies note at the top of Safety: a bordered note in body-size text, not a small hint */
.register-copies { margin: 0 0 var(--space-3); padding: var(--space-3); border: var(--border-status) solid var(--c-border-gp);
  border-radius: var(--radius-md); color: var(--c-heading); font-size: 1rem; }
.register-row__file-missing { text-decoration: none; }
.register-section__not-needed { margin: 0; padding: var(--space-2) 0; border-top: 1px solid var(--c-line); color: var(--c-text-2); }
/* F-87 (board AH option A): the grey question directly above the bold answer, Copy on the right, laptop as phone */
.register-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "q copy" "a copy";
  column-gap: var(--space-3); row-gap: var(--space-1); align-items: center;
  padding: var(--space-2) 0; border-top: 1px solid var(--c-line); }
.register-row__q { grid-area: q; color: var(--c-text-2); font-size: 0.875rem; }
.register-row__a { grid-area: a; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-width: 0;
  color: var(--c-text); overflow-wrap: anywhere; }
.register-row__value { color: var(--c-heading); font-weight: 700; user-select: text; }
.register-row__dots { color: var(--c-heading); letter-spacing: 0.1em; }
.register-row__note { flex-basis: 100%; color: var(--c-text-2); font-size: 0.8125rem; }
.register-row__fix, .register-row__download { display: inline-flex; align-items: center; gap: var(--space-1); min-height: var(--tap); }
/* F-104 (board AN): an expired Gas, EICR or EPC: the red chip, white words and the 44px link to the item page in a
   red-bordered box, above Download to upload. Red only on the border and the chip (B22 R4). Spans only: a row holds
   no div. Tokens only. */
.register-row__expired { flex-basis: 100%; display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-1); padding: var(--space-2) var(--space-3); border: var(--border-status) solid var(--c-strip-red);
  border-radius: var(--radius-md); }
.register-row__expired-text { color: var(--c-heading); font-weight: 600; overflow-wrap: anywhere; }
.register-row__copy { grid-area: copy; justify-self: end; }
.register-copy, .register-reveal, .register-copy-all { min-height: var(--tap); min-width: var(--tap); }
.register-copy[hidden], .register-reveal[hidden], .register-copy-all[hidden], .register-row__dots[hidden],
.register-row__value[hidden] { display: none; }
@media (max-width: 640px) {
  .register-row { grid-template-columns: 1fr; grid-template-areas: "q" "a" "copy"; gap: var(--space-2); margin-bottom: var(--space-2); padding: var(--space-3);
    border: 1px solid var(--c-line); border-radius: var(--radius-md); background: var(--c-tint); }
  .register-row__copy { justify-self: stretch; }
  .register-row__copy .register-copy { width: 100%; }
}
/* end L30 Register Task 8 */

/* F-89 (board AI): the Marketing tab's "Registration numbers for your advert" card. Each row: the grey label, the
   number (mono, bold) or a grey italic "Not registered yet", the source note, and Copy on the right (44px; hidden
   without JavaScript, the number stays selectable). Tokens only. */
.advert-numbers__note { margin: 0 0 var(--space-2); }
.advert-numbers__rows { list-style: none; margin: 0; padding: 0; }
.advert-numbers__row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
  gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--c-line); }
.advert-numbers__main { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
.advert-numbers__label { color: var(--c-text-2); font-size: 0.875rem; }
.advert-numbers__value { color: var(--c-heading); font-family: var(--font-mono); font-weight: 700; overflow-wrap: anywhere;
  user-select: text; }
.advert-numbers__blank { color: var(--c-text-2); font-style: italic; }
.advert-numbers__source { color: var(--c-text-2); font-size: 0.8125rem; }
.advert-numbers__copy { min-height: var(--tap); min-width: var(--tap); }
.advert-numbers__copy[hidden] { display: none; }
/* F-96 (board AK): "Check your band on GOV.UK" (44px), on the advert card's council tax row and on its own line
   under the Council tax band hint in Edit property details. */
.advert-numbers__more, .council-tax-link { display: inline-flex; align-items: center; align-self: flex-start; justify-self: start;
  min-height: var(--tap);
  font-size: 0.875rem; }
/* end F-89 */

/* L30 Register Task 10 (board AE): "Changes to update in the register" (data-border red or orange), its lines (text,
   chip, Mark as updated in the register), the foot (Copy changed details, Mark all as updated) and the note. Mark as
   updated is details.register-mark: the summary is the secondary button, the date box opens in place (no
   JavaScript needed). A changed row has an amber (--due-soon) or red (--overdue) left edge, the "Changed: copy this"
   marker in capitals (CSS only, so screen readers read words) and "Was ..." under the answer. 44px targets. */
.register-changes__lines { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.register-changes__line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3);
  padding: var(--space-2) 0; border-top: 1px solid var(--c-line); }
.register-changes__text { flex: 1 1 14rem; color: var(--c-heading); }
.register-changes__foot { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2);
  margin-top: var(--space-3); }
.register-changes__note { margin: var(--space-2) 0 0; }
.register-copy-changed { min-height: var(--tap); }
.register-copy-changed[hidden], .register-mark__cancel[hidden] { display: none; }
details.register-mark { padding: 0; background: none; border: 0; box-shadow: none; }
details.register-mark > summary.register-mark__toggle { display: inline-flex; min-height: var(--tap); }
.register-mark__form { display: grid; gap: var(--space-2); max-width: 20rem; margin-top: var(--space-2); }
.register-mark__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.register-mark__save, .register-mark__cancel { min-height: var(--tap); }
.register-row--changed { padding-left: var(--space-3); border-left: 4px solid var(--c-strip-amber); }
.register-row--overdue { border-left-color: var(--c-strip-red); }
.register-row__changed { flex-basis: 100%; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--c-soon); }
.register-row--overdue .register-row__changed { color: var(--c-text); }  /* red stays on the edge and the chip (B22 R4) */
.register-row__was { flex-basis: 100%; color: var(--c-text-2); font-size: 0.8125rem; }
@media (max-width: 640px) {
  .register-changes__line details.register-mark, .register-changes__foot > * { flex: 1 1 100%; }
  details.register-mark > summary.register-mark__toggle, .register-copy-changed { width: 100%; justify-content: center; }
}
/* end L30 Register Task 10 */

/* F-91 (board AJ, option 1): the Overview "Landlord register" tile (F-100: in .overview-register). Its border comes
   from data-border (the plain border before go-live, then green, orange or red). __top: the title and the 44px
   "Open" link; __head the state in white; __sub muted; __list lines: the short address (and change) in white with
   the chip on the right (red only as the solid chip, never small red text on navy), each a 44px link. Tokens only. */
.landlord-register { gap: var(--space-2); }
.landlord-register__top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.landlord-register__name { font-weight: 600; color: var(--c-heading); }
.landlord-register__open {
  display: inline-flex; align-items: center; min-height: var(--tap); min-width: var(--tap); justify-content: flex-end;
  color: var(--c-link); font-size: 0.875rem; text-decoration: underline;
}
.landlord-register__open:hover { color: var(--c-link-hover); }
.landlord-register__head { font-weight: 700; color: var(--c-heading); }
.landlord-register__sub { font-size: 0.8125rem; color: var(--c-text-2); }
.landlord-register__list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); }
.landlord-register__list li { border-top: 1px solid var(--c-line); }
.landlord-register__list a {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: var(--tap);
  padding: var(--space-1) 0; color: var(--c-text); text-decoration: none; overflow-wrap: anywhere;
}
.landlord-register__list a:hover .landlord-register__text { text-decoration: underline; }
.landlord-register__text { min-width: 0; font-size: 0.875rem; }
.landlord-register__list .chip { flex: none; white-space: nowrap; }
.landlord-register__more { padding: var(--space-2) 0; font-size: 0.8125rem; color: var(--c-text-2); }
/* end F-91 */

/* L26 Snap a certificate (board AF): .snap is the line above the always-shown record form (hidden until app.js shows
   it), with the phone choice (.snap__phone: Take a photo, Choose a file), the reading state (.snap__reading with a
   turning ring and Stop) and the banners. Tags under a label: .snap-tag--read (accent on the accent background),
   --cant (orange on the neutral chip, as the information tags), --hint (grey). A read field has an accent edge, a
   field it could not read an orange one. Banners are left-edged cards; red is only ever an edge, never text.
   .snap__paused is the grey line at the monthly limit. */
.snap { display: grid; gap: var(--space-3); margin-bottom: var(--space-4); }
.snap[hidden], .snap__phone[hidden], .snap__reading[hidden] { display: none; }
.snap__intro { display: grid; gap: var(--space-1); padding-bottom: var(--space-3); border-bottom: 1px solid var(--c-line); }
.snap__line, .snap__saved { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.snap__hint { margin: 0; }
.snap__button { flex: none; }
.snap__phone { display: grid; gap: var(--space-2); padding: var(--space-3); border-radius: var(--radius-lg);
  background: var(--c-tint); border: 1px solid var(--c-accent); }
.snap__phone p { margin: 0; }
.snap__phone-title { font-weight: 700; color: var(--c-heading); }
.snap__phone .btn { width: 100%; }
.snap__reading { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-3);
  border-radius: var(--radius-lg); background: var(--c-tint); border: 1px solid var(--c-line); }
.snap__reading-text { flex: 1 1 14rem; display: grid; gap: 2px; color: var(--c-heading); }
.snap__spinner { flex: none; width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--c-line);
  border-top-color: var(--c-accent); animation: snap-spin 0.9s linear infinite; }
@keyframes snap-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .snap__spinner { animation: none; } }
.snap__stop, .snap__cancel { min-height: var(--tap); padding: 0 var(--space-2); border: 0; background: transparent;
  color: var(--c-link); font-weight: 600; text-decoration: underline; }
.snap__cancel { color: var(--c-text-2); }
.snap__stop:hover, .snap__cancel:hover { background: transparent; color: var(--c-link-hover); }
.snap__banners { display: grid; gap: var(--space-2); }
.snap__banners:empty { display: none; }
.snap__banners > .hint { margin: 0; }
.snap-banner { display: grid; gap: var(--space-1); background: var(--c-card); color: var(--c-text);
  border: 1px solid var(--c-card-border); border-left: 4px solid var(--c-accent); overflow-wrap: anywhere; }
.snap-banner--amber { border-color: var(--c-border-orange); border-left-color: var(--c-border-orange); }
.snap-banner--red { border-color: var(--c-border-red); border-left-color: var(--c-border-red); }
.snap-tag { justify-self: start; font-size: 0.75rem; font-weight: 700; line-height: 1.4; padding: 2px var(--space-2);
  border-radius: var(--radius-sm); }
.snap-tag--read { background: var(--c-accent-bg); color: var(--c-accent); }
.snap-tag--cant { background: var(--c-neutral-bg); color: var(--c-soon); }
.snap-tag--hint { padding: 0; font-weight: 400; color: var(--c-text-2); }
.certificate-kind > .snap-tag { margin-bottom: var(--space-1); }
.snap-field--read { border-color: var(--c-accent); }
.snap-field--cant { border-color: var(--c-border-orange); }
/* An amber field (Unsatisfactory) keeps its amber border after a read: an unsafe result must not look fine. */
.field--amber.snap-field--read { border-color: var(--c-border-orange); }
.snap-problems, .snap-conditions { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md);
  background: var(--c-tint); color: var(--c-text); border: 1px solid var(--c-border-orange); overflow-wrap: anywhere; }
.snap-conditions { border-color: var(--c-accent); }
.snap-problems p, .snap-conditions p { margin: 0; }
.snap-problems ul, .snap-conditions ul { margin: var(--space-1) 0 0; padding-left: var(--space-5); }
.snap-file-note { margin: var(--space-1) 0 0; }
.snap__paused { margin: 0 0 var(--space-4); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md);
  background: var(--c-tint); border: 1px solid var(--c-line); color: var(--c-text-2); }
/* L26 after Save (board AF screen 6): .snap-after is the problems card (an orange edge, as the problems card before
   Save) with one row per problem (.snap-after__row: the line, then Open a repair and Not now, wrapping under the line
   on a phone; .snap-after__more the "and N more problems: see Notes" line); .snap-contact the Add this engineer
   to Contacts line; .snap-reminder the licence or deposit reminder. */
.snap-after { border-color: var(--c-border-orange); overflow-wrap: anywhere; }
.snap-after__rows { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: grid; }
.snap-after__row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-3) 0; border-top: 1px solid var(--c-line); }
.snap-after__row[hidden] { display: none; }
.snap-after__line { flex: 1 1 16rem; color: var(--c-text); }
.snap-after__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.snap-after__actions form { margin: 0; }
.snap-after__actions .btn { min-height: var(--tap); }
.snap-contact { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.snap-contact p, .snap-contact form { margin: 0; }
.snap-contact .btn { min-height: var(--tap); }
.snap-reminder { border-color: var(--c-accent); overflow-wrap: anywhere; }
.snap-after__more { margin: var(--space-2) 0 0; }
.snap-after, .snap-contact, .snap-reminder { margin-bottom: var(--space-4); }
/* end L26 Snap */
