/* =====================================================================
   LD Workflows — Design System
   ---------------------------------------------------------------------
   Centralised, project-wide responsive styles. Loaded last (after
   Bootstrap 3 + styles_bt3 + routstyle) so it can refine the theme.

   Mirror any change to BOTH:
     - staticfiles/styles/ld-design-system.css   (source / dev)
     - static/styles/ld-design-system.css        (collected / prod)

   Contents
     1. Design tokens (:root variables)
     2. Typography
     3. Buttons
     4. Forms
     5. Tables
     6. Cards / panels
     7. Responsive helpers
   ===================================================================== */

/* ============================ 1. TOKENS ============================= */
:root {
    /* Brand / theme colour (the teal used by the primary call-to-action) */
    --ld-primary:        #59ADA8;
    --ld-primary-hover:  #45b3ab;
    --ld-primary-active: #65BB99;
    --ld-primary-soft:   #C9D0CA;   /* tints, table headers, hovers */

    /* Accents */
    --ld-danger:   #E15A58;
    --ld-warning:  #f6a821;
    --ld-success:  #65BB99;
    --ld-success-dark: #4fa882;   /* darker shade for .btn-success hover/active */
    --ld-info:     #5bc0de;
    --ld-hard:     #234C5A;   /* brand navy — used by .btn-primary */
    --ld-hard-dark:#1b3a46;   /* darker navy for .btn-primary hover/active */

    /* Warm peach — used by .btn-ld-warning toolbar buttons */
    --ld-ld-warning:       #F6CC9F;
    --ld-ld-warning-hover: #f0bd86;   /* darker peach for hover/active */

    /* Neutrals */
    --ld-text:        #3a3a3a;
    --ld-text-muted:  #8a8f99;
    --ld-border:      #e3e6ea;
    --ld-bg-soft:     #f7f9fa;
    --ld-white:       #ffffff;

    /* Shape & depth */
    --ld-radius:        6px;
    --ld-radius-pill:   50px;
    --ld-shadow-sm:     0 1px 3px rgba(0, 0, 0, .12);
    --ld-shadow:        0 2px 10px rgba(0, 0, 0, .08);

    /* Type */
    --ld-font: 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* ========================== 2. TYPOGRAPHY =========================== */
body {
    font-family: var(--ld-font);
    color: var(--ld-text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: var(--ld-font);
    font-weight: 600;
    color: var(--ld-hard);
}

a { color: var(--ld-primary); }
a:hover, a:focus { color: var(--ld-primary-active); }

.text-muted { color: var(--ld-text-muted) !important; }

/* ============================ 3. BUTTONS ============================ */
/* .btn-primary is themed with the LD brand navy (#234C5A) so primary actions
   match across the whole app. The other Bootstrap button classes
   (.btn-default, .btn-danger, …) keep their stock look; use .btn-ld / .btn-cta
   for the teal branded styles. */
.btn-primary,
.btn-primary.disabled,
.btn-primary[disabled] {
    background-color: var(--ld-hard);
    border-color: var(--ld-hard);
    color: var(--ld-white);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
    background-color: var(--ld-hard-dark);
    border-color: var(--ld-hard-dark);
    color: var(--ld-white);
}
.btn-primary:focus,
.btn-primary.focus {
    box-shadow: 0 0 0 3px rgba(35, 76, 90, .35);
}

/* Brand-coloured success button (#65BB99) */
.btn-success,
.btn-success.disabled,
.btn-success[disabled] {
    background-color: var(--ld-success);
    border-color: var(--ld-success);
    color: var(--ld-white);
}
.btn-success:hover,
.btn-success:focus,
.btn-success.focus,
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
    background-color: var(--ld-success-dark);
    border-color: var(--ld-success-dark);
    color: var(--ld-white);
}
.btn-success:focus,
.btn-success.focus {
    box-shadow: 0 0 0 3px rgba(101, 187, 153, .35);
}

/* Solid brand button — the standard LD action button */
.btn-ld {
    background-color: var(--ld-primary);
    border: 1px solid var(--ld-primary);
    border-radius: var(--ld-radius);
    color: var(--ld-white);
    font-weight: 500;
    transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.btn-ld:hover, .btn-ld:focus,
.btn-ld:active, .btn-ld.active {
    background-color: var(--ld-primary-hover);
    border-color: var(--ld-primary-hover);
    color: var(--ld-white);
    text-decoration: none;
}
.btn-ld:focus, .btn-ld:active:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(84, 195, 187, .35);
}

/* Call-to-action / pill — the prominent branded action style.
   Use .btn-cta (or the legacy .call-to-action) for primary CTAs. */
.btn-cta,
.call-to-action {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 20px;
    border: none;
    border-radius: var(--ld-radius-pill);
    background-color: var(--ld-primary);
    color: var(--ld-white);
    font-weight: 500;
    line-height: 1.2;
    box-shadow: var(--ld-shadow-sm);
}
.btn-cta:hover, .btn-cta:focus,
.call-to-action:hover, .call-to-action:focus {
    background-color: var(--ld-primary-hover);
    color: var(--ld-white);
    text-decoration: none;
}

/* Outline pill — secondary actions that still read as branded */
.btn-outline-primary {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 20px;
    border: 1px solid var(--ld-primary);
    border-radius: var(--ld-radius-pill);
    background: transparent;
    color: var(--ld-primary);
    font-weight: 500;
}
.btn-outline-primary:hover, .btn-outline-primary:focus {
    background-color: var(--ld-primary);
    color: var(--ld-white);
    text-decoration: none;
}

/* A wrapping toolbar of actions (e.g. page headers). Every .btn inside it
   becomes a brand pill; inline <form>s line up with the buttons. Add
   .ld-actions-end to right-align. */
.ld-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    float: none !important;
}
.ld-actions.ld-actions-end { justify-content: flex-end; }
.ld-actions form {
    display: inline-flex;
    flex-wrap: wrap;      /* a form holding several buttons must be able to wrap */
    align-items: center;
    gap: 8px;
    margin: 0;
    max-width: 100%;
}
.ld-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 8px 18px;
    border: none;
    border-radius: var(--ld-radius-pill);
    background-color: var(--ld-primary);
    color: var(--ld-white);
    font-weight: 500;
    font-size: 14px;
    line-height: 1.2;
    white-space: nowrap;
    box-shadow: var(--ld-shadow-sm);
}
.ld-actions .btn:hover,
.ld-actions .btn:focus {
    background-color: var(--ld-primary-hover);
    color: var(--ld-white);
    text-decoration: none;
}
.ld-actions .btn i { font-size: 13px; }
/* White toolbar button (e.g. a dropdown toggle) */
.ld-actions .btn-group > .dropdown-toggle,
.ld-actions .btn.btn-white {
    background-color: var(--ld-white);
    color: var(--ld-text);
    border: 1px solid var(--ld-border);
}
.ld-actions .btn-group > .dropdown-toggle:hover,
.ld-actions .btn-group > .dropdown-toggle:focus,
.ld-actions .btn-group.open > .dropdown-toggle,
.ld-actions .btn.btn-white:hover,
.ld-actions .btn.btn-white:focus {
    background-color: var(--ld-bg-soft);
    color: var(--ld-text);
}
/* Warm peach toolbar button (overrides the default teal pill) */
.ld-actions .btn.btn-ld-warning {
    background-color: var(--ld-ld-warning);
    border: 1px solid var(--ld-ld-warning);
    color: var(--ld-text);
}
.ld-actions .btn.btn-ld-warning:hover,
.ld-actions .btn.btn-ld-warning:focus {
    background-color: var(--ld-ld-warning-hover);
    border-color: var(--ld-ld-warning-hover);
    color: var(--ld-text);
}
/* Inline selects in a toolbar (e.g. a tax picker) match the pill height */
.ld-actions .form-control {
    display: inline-block;
    width: auto;
    height: 38px;
    border-radius: var(--ld-radius-pill);
}
@media (max-width: 767px) {
    /* Both selectors are needed: `.ld-actions` alone is (0,1,0) and loses to
       `.ld-actions.ld-actions-end { justify-content: flex-end }` above, which
       is (0,2,0) — media queries add no specificity. Without the second
       selector this rule was a no-op (plain .ld-actions is already
       flex-start), so right-aligned toolbars stayed hard against the right
       edge on phones and wrapped into a ragged column. */
    .ld-actions,
    .ld-actions.ld-actions-end { justify-content: flex-start; }
    /* Long labels ("Show notifications assigned to me") must wrap rather than
       push the button past the edge of the card that holds them. */
    .ld-actions .btn {
        max-width: 100%;
        white-space: normal;
        text-align: left;
    }
}

/* ============================= 4. FORMS ============================= */
.form-control {
    border-radius: var(--ld-radius);
    border-color: var(--ld-border);
    box-shadow: none;
    color: var(--ld-text);
}
.form-control:focus {
    border-color: var(--ld-primary);
    box-shadow: 0 0 0 3px rgba(84, 195, 187, .25);
}
label { font-weight: 600; }

/* Hide the "Current timezone: …" hint the base JS appends after every date
   input — it clutters filter forms below each date field. */
.current-timezone { display: none; }

/* Legacy Bootstrap 2 form helpers (BS3 dropped these) — give old inputs
   that still use these classes a proper, full-width control look. */
.input-block-level,
.select-large,
.Input_widthsamll,
.Select_widthsamll {
    display: block;
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    color: var(--ld-text);
    background-color: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-sizing: border-box;
}
.labe_margibbtm { display: block; margin-bottom: 5px; font-weight: 600; }

/* ============================= 5. TABLES =========================== */
.table {
    background-color: var(--ld-white);
}
.table > thead > tr > th {
    background-color: var(--ld-hard);
    color: var(--ld-white);
    border-bottom: none;
    font-weight: 600;
    vertical-align: middle;
}
.table-bordered > thead > tr > th { border-color: var(--ld-primary-hover); }
.table > tbody > tr > td { vertical-align: middle; }
.table-hover > tbody > tr:hover { background-color: var(--ld-primary-soft); }
.table-striped > tbody > tr:nth-of-type(odd) { background-color: var(--ld-bg-soft); }

/* Let any wide table scroll horizontally on small screens even when the
   .table-responsive class was put on the <table> itself (a Bootstrap-3
   no-op) instead of on a wrapping div. */
@media (max-width: 991px) {
    table.table-responsive {
        display: block;
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Responsive column chooser injected by rwd-table.js on .data-table tables.
   The plugin inserts <div class="table-menu-wrapper"> just before the table,
   holding a toggle button and a "Choose columns" checkbox menu. These styles
   live here so every collection-based page keeps the chooser — styles.css,
   which used to provide them, is not loaded by the collection base. */
.table-menu-wrapper {
    position: relative;
    min-height: 1px;
    margin-bottom: 5px;
    text-align: right;
}
.table-menu-btn,
.table-menu-btn:hover,
.table-menu-btn:focus {
    display: inline-block;
    padding: 4px 8px;
    color: var(--ld-text);
    font-size: 18px;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
}
.table-menu-btn:hover { color: var(--ld-primary); }
/* Hide the plugin's "Display" label, show a hamburger icon instead */
.table-menu-btn span { display: none; }
.table-menu-btn i::before {
    font-family: "Font Awesome 5 Free", "FontAwesome", sans-serif;
    font-weight: 900;
    content: "\f0ca"; /* fa-list */
}
.table-menu {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 999;
    min-width: 210px;
    padding: 14px 18px;
    text-align: left;
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow);
}
.table-menu::before {
    content: "Choose columns:";
    display: block;
    margin-bottom: 8px;
    font-size: 16px;
    font-weight: 600;
    color: var(--ld-hard);
}
.table-menu ul { list-style: none; margin: 0; padding: 0; }
.table-menu li { padding: 4px 0; white-space: nowrap; }
.table-menu li label { margin: 0 0 0 6px; font-weight: 400; cursor: pointer; }
.table-menu-hidden { display: none; }

/* Columns marked .hidden-fields start collapsed and are revealed from the
   chooser (rwd-table adds .enhanced to the table once it has run, and
   copies each th's classes onto its cells). Custom-field columns and the
   audit columns on the group history rely on this. */
.enhanced th.hidden-fields,
.enhanced td.hidden-fields { display: none; }

/* Columns that only carry a record id for the JS to read (the Stock list
   ships an "Id" and a "Variant Id" column). Marked .persist as well, so the
   column chooser never offers to bring them back. */
th.datahide,
td.datahide { display: none; }

/* ========================= 6. CARDS / PANELS ======================= */
.ld-card {
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow);
    padding: 20px;
    margin-bottom: 20px;
}
/* Also used as the section heading inside a .panel-body on the record forms,
   which is not a .ld-card — without the second selector those headings fell
   back to a bare <h3>. */
.ld-card .ld-card-title,
.panel .ld-card-title {
    margin: 0 0 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--ld-border);
    font-size: 18px;
    font-weight: 600;
}

/* First card in a sidebar column that sits next to a .ld-list-table-card —
   .ld-card has no top margin of its own, so without this it rides 16px
   higher than the panel beside it. */
.ld-sidebar-card { margin-top: 16px; }

/* Two-column label/value grid for detail panels inside an .ld-card.
   Children tagged .ld-info-item sit two-up; .ld-info-full span the row
   (use for long values such as addresses). Any other direct child
   (e.g. a hidden .modal, or legacy stacked fields) falls back to full
   width so it never wedges into a half column. */
.ld-info-grid {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
}
.ld-info-grid > .ld-info-item,
.ld-info-grid > .ld-info-full {
    padding-right: 20px;
    margin-bottom: 12px;
    line-height: 1.5;
}
.ld-info-item { flex: 0 0 50%; max-width: 50%; }
.ld-info-full { flex: 0 0 100%; max-width: 100%; }
.ld-info-grid > *:not(.ld-info-item):not(.ld-info-full) {
    flex: 0 0 100%;
    max-width: 100%;
}
@media (max-width: 767px) {
    .ld-info-item { flex: 0 0 100%; max-width: 100%; }
}

/* A header row: title on the left, actions on the right, wraps on mobile */
.ld-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 15px;
    margin-top: 15px;
}
.ld-page-head > .ld-page-title { margin: 0 auto 0 0; }   /* pin title left */

/* ======================= 7. RESPONSIVE HELPERS ===================== */
img.ld-responsive,
.ld-img-responsive { max-width: 100%; height: auto; }

@media (max-width: 767px) {
    /* Stop legacy floated header rows from overlapping on phones */
    .ld-page-head { justify-content: flex-start; }
}

/* ========================== 8. LIST PAGES ========================= */
/* Shared layout for the record-list screens (Quotes, Sales orders,
   Invoices, Credit notes): an outlined toolbar card holding the title,
   an optional search box and the action buttons on a single line,
   followed by an outlined card that wraps the results table. Bootstrap 3
   .panel.panel-default supplies the outline box; these classes lay the
   contents out and pin the title to the left. */
.ld-list-toolbar-card,
.ld-list-table-card {
    margin-top: 16px;
    margin-bottom: 16px;
}
.ld-list-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}
.ld-list-title {                 /* matches the Quotes list title */
    margin: 0 auto 0 0;          /* pin title left → search/actions go right */
    padding: 0;
    border: 0;
    font-size: 22px;
    font-weight: 600;
    color: #1a6e6b;
}
.ld-list-search { margin: 0; width: 100%; max-width: 340px; }
.ld-list-search .input-group { width: 100%; }
.ld-list-actions { flex: 0 0 auto; margin: 0; min-width: 0; max-width: 100%; }
/* A toolbar carrying more than one search field (e.g. Contacts searches by
   name and by postcode) — each box shares the row instead of filling it. */
/* When the toolbar's title needs a subtitle or description under it, wrap the
   pair in .ld-list-heading. .ld-list-title's own `margin-right: auto` only
   pushes actions right when the title is a direct child of .ld-list-controls;
   inside a wrapper it applies to the title within that wrapper instead, and
   the actions end up beside the heading rather than at the right edge. */
.ld-list-controls > .ld-list-heading { flex: 1 1 auto; min-width: 0; margin-right: auto; }

.ld-list-controls .search-box { flex: 1 1 190px; max-width: 260px; }
.ld-list-controls .search-box .input-group { width: 100%; }

/* A table sitting directly under a toolbar row needs a little air. On the
   list screens the rwd-table column chooser is injected between the two and
   supplies it, but a plain table (the address list on a company detail page)
   butts straight up against the buttons. .ld-list-body covers the same case
   where the table is wrapped in a container (an ajax-refreshed list). */
.ld-list-controls + table,
.ld-list-controls + .ld-list-body { margin-top: 12px; }

@media (max-width: 767px) {
    .ld-list-controls { justify-content: flex-start; }
    .ld-list-title { margin-bottom: 8px; }
    .ld-list-search { max-width: 100%; }
    .ld-list-controls .search-box { flex: 1 1 100%; max-width: 100%; }
    .ld-list-actions { flex: 1 1 100%; max-width: 100%; flex-wrap: wrap; }
}

/* ========================= 9. ACTIVITY LOG ======================== */
/* The shared, read-only activity-history panel rendered by
   {% render_activity_logs %} on every detail page. Kept compact (smaller
   font, tighter cells) so the history reads as secondary metadata. */
.activity-logs-card { margin-top: 10px; }
.activity-logs-card .panel-heading .activity-logs-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--ld-hard);
}
.activity-logs-table,
.activity-logs-table > thead > tr > th,
.activity-logs-table > thead > tr > td,
.activity-logs-table > tbody > tr > th,
.activity-logs-table > tbody > tr > td,
.activity-logs-table > tr > th,
.activity-logs-table > tr > td {
    font-size: 12px;
    line-height: 1.4;
}
.activity-logs-table > thead > tr > th,
.activity-logs-table > tr > th {
    font-weight: 600;
}
.activity-logs-table > thead > tr > th,
.activity-logs-table > thead > tr > td,
.activity-logs-table > tbody > tr > th,
.activity-logs-table > tbody > tr > td,
.activity-logs-table > tr > th,
.activity-logs-table > tr > td {
    padding: 6px 10px;
}

/* ======================= 10. CRM TAB NAVIGATION =================== */
/* crm/tab_navigation.django.html is shared with the legacy Bootstrap-2
   pages, so it still ships a mobile dropdown (.hidden-desktop) plus the
   full tab row (.visible-desktop) and an inline <style> that paints the
   "Add …" pill blue. Bootstrap 3 defines neither responsive class, so
   both lists rendered at once. Restore the intended behaviour here —
   this stylesheet is only loaded by the collection base template, so the
   Bootstrap-2 pages keep their existing look. */
.tabbable { position: relative; }
.tabbable .visible-desktop { display: none; }
.tabbable .hidden-desktop { display: block; }
@media (min-width: 768px) {
    .tabbable .visible-desktop { display: block; }
    .tabbable .hidden-desktop { display: none; }
}

/* Pin the "Add a contact" pill to the tab row rather than letting the
   legacy negative-offset float overlap the tabs. */
.tabbable .nav-call {
    position: absolute;
    top: 0;
    right: 0;
    float: none;
    margin: 0;
}
/* Beat the include's inline `.btn-primary.call-to-action { color: #049cdb }`
   (same specificity, but later in the document) so the pill keeps readable
   white text on the brand teal. */
.tabbable .nav-call .btn-primary.call-to-action,
.tabbable .nav-call .btn-primary.call-to-action:hover,
.tabbable .nav-call .btn-primary.call-to-action:focus {
    padding: 6px 16px;
    color: var(--ld-white);
    font-size: 14px;
}
/* Below 768px the pill can no longer share the tab row, so it drops beneath
   the tabs — it needs breathing room on both sides, and its buttons must be
   able to wrap instead of running off the screen. */
@media (max-width: 767px) {
    .tabbable .nav-call {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        position: static;
        margin: 12px 0 15px;
    }
    .tabbable .nav-call .btn { margin: 0; max-width: 100%; white-space: normal; }
}

/* Warehouse (stock/tab_navigation.django.html) ships twelve tabs in one strip.
   At Bootstrap's default tab padding they no longer fit the row, so the last
   one wrapped onto a second line: that pushed the page content down and left
   the active tab stranded above the underline.

   The fix is deliberately nothing but a padding change. The row keeps
   Bootstrap's own float layout, which is what makes the selected tab read as
   selected: `.nav-tabs > li` carries `margin-bottom: -1px` so each tab
   overlaps the strip's underline, and the active tab paints a transparent
   bottom border over that 1px, opening it onto the panel below — the Contacts
   list look.

   Do NOT make this row a flex/scroll container. `overflow` clips at the
   padding box, which eats that 1px overlap, and the underline then runs
   straight through under the selected tab. */
.tabbable.ld-tabs-compact .nav-tabs.visible-desktop > li > a {
    padding: 10px 9px;
    white-space: nowrap;
}

/* The "Back to …" link ships as a pull-right <li> inside the strip, so as
   soon as the tabs fill the row it wrapped onto a second line — pushing the
   underline down and stranding the active tab above it. Lift it out of the
   flow: it sits at the top right of .tabbable (which is position: relative),
   level with the tabs, and the tab row stays a single line whatever the
   label says. Below 768px the desktop row is hidden entirely and the back
   link rides in the mobile dropdown, so this only applies from 768px up. */
@media (min-width: 768px) {
    .tabbable.ld-tabs-compact .nav-tabs.visible-desktop > li.pull-right {
        position: absolute;
        top: 0;
        right: 0;
    }
}

/* Twelve tabs and the "Add …" pill cannot share a row at any sane padding,
   and reserving room for the pill on the strip only forces the wrap back. On
   the warehouse pages that have one, drop it under the strip instead of
   floating it over the last tabs. */
@media (min-width: 768px) {
    .tabbable.ld-tabs-compact.has-nav-call .nav-call {
        position: static;
        float: none;
        margin: 10px 0 0;
        text-align: right;
    }
}

/* ====================== 11. GROUP COLOUR SWATCH =================== */
/* The group lists mark each row with <bull class="label-color-xxxxxx">, a
   small round colour chip. Both the element rule and most of the palette
   live in the Bootstrap-2 styles.css, which the collection base does not
   load — styles_bt3.css only carries five of the colours — so the chip
   rendered as nothing. Restore the dot and the remaining swatches. */
bull {
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-bottom: 1px;
    border-radius: 50%;
    background-color: #555555;
}
.label-color-000    { background-color: #000; }
.label-color-1f1f1f { background-color: #1f1f1f; }
.label-color-525252 { background-color: #525252; }
.label-color-0d2d78 { background-color: #0d2d78; }
.label-color-123fa6 { background-color: #123fa6; }
.label-color-780d0d { background-color: #780d0d; }
.label-color-a61212 { background-color: #a61212; }
.label-color-12780d { background-color: #12780d; }
.label-color-19a612 { background-color: #19a612; }
.label-color-300378 { background-color: #300378; }
.label-color-4405a9 { background-color: #4405a9; }
.label-color-6c530c { background-color: #6c530c; }
.label-color-9a7711 { background-color: #9a7711; }
.label-color-78036d { background-color: #78036d; }
.label-color-a9059b { background-color: #a9059b; }
.label-color-0a797f { background-color: #0a797f; }
.label-color-0da6af { background-color: #0da6af; }

/* The group's description sits under its name as secondary text (also
   styles.css only). */
.group-description {
    color: var(--ld-text-muted);
    font-size: 12px;
}

/* ==================== 12. TOOLBAR FILTER DROPDOWN ================= */
/* collection/snippets/corporate_identity_filter.html ships as a full-width
   .row holding a floated .navbar-nav — fine in a page header, but it fights
   the flex toolbar on the list pages, and its .filter_bg skin is scoped to
   `.routes` in routstyle.css so the toggle renders as bare text elsewhere.
   Wrap the include in .ld-list-filter to flatten it into a single white
   pill that sits inline with the other toolbar buttons. */
.ld-list-filter { flex: 0 0 auto; }
.ld-list-filter .row,
.ld-list-filter [class*="col-"],
.ld-list-filter #filter_results {
    margin: 0;
    padding: 0;
}
.ld-list-filter .nav {
    display: flex;
    float: none;
    margin: 0;
}
.ld-list-filter .nav > li { float: none; list-style: none; }
.ld-list-filter .nav > li > a.dropdown-toggle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 18px;
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius-pill);
    background: var(--ld-white);
    color: var(--ld-text);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    box-shadow: var(--ld-shadow-sm);
}
.ld-list-filter .nav > li > a.dropdown-toggle:hover,
.ld-list-filter .nav > li > a.dropdown-toggle:focus,
.ld-list-filter .nav > .open > a.dropdown-toggle {
    background: var(--ld-bg-soft);
    color: var(--ld-text);
    text-decoration: none;
}
.ld-list-filter .dropdown-menu {
    right: 0;
    left: auto;
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow);
}
/* Bootstrap collapses navbar dropdowns into the flow below 768px; this one
   is not in a navbar, so keep it a real dropdown at every width. */
@media (max-width: 767px) {
    .ld-list-filter .navbar-nav .open .dropdown-menu {
        position: absolute;
        float: left;
        width: auto;
        margin-top: 2px;
        background-color: var(--ld-white);
        border: 1px solid rgba(0, 0, 0, .15);
        box-shadow: var(--ld-shadow);
    }
    .ld-list-filter .navbar-nav .open .dropdown-menu > li > a { padding: 3px 20px; }
}

/* ===================== 13. ROW META / ICON LISTS ================== */
/* Secondary "By: … / posted …" byline under a record's title in a list
   cell or a modal header. .log-user / .log-time were floated opposite
   each other by styles.css, which the collection base does not load —
   without it they ran together as plain body text. */
.enquiry-meta,
.ld-row-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 2px 0 0;
    color: var(--ld-text-muted);
    font-size: 12px;
}
.enquiry-meta .log-time,
.ld-row-meta .log-time { margin-left: auto; }
.enquiry-subject { font-weight: 600; }
.enquiry-url-row { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.enquiry-url-row > a:first-child { word-break: break-all; }

/* A list of detail lines each led by a Font Awesome icon (contact details
   in a modal, for instance). Replaces the legacy .inline-text/.glyphicons
   pattern, whose icons were supplied by styles.css. */
.ld-icon-list {
    list-style: none;
    margin: 0 0 6px;
    padding: 0;
}
.ld-icon-list li { padding: 4px 0; }
.ld-icon-list li > i {
    width: 18px;
    margin-right: 6px;
    color: var(--ld-primary);
    text-align: center;
}

/* ====================== 14. THUMBNAIL GRID ======================= */
/* Bootstrap 3 dropped the Bootstrap-2 `.thumbnails` list wrapper (only the
   inner `.thumbnail` survived), so the email-template galleries rendered as
   a bulleted list of full-width images. .ld-thumb-grid lays the tiles out
   on the Bootstrap 3 grid and crops each screenshot to a uniform height,
   anchored to the top so the header of the email stays visible. */
/* No `overflow: hidden` here — a "Preview template" dropdown lives in the
   caption and must be free to spill outside the tile. The image corners are
   rounded on the image/.crop instead. */
.ld-thumb-grid .thumbnail {
    position: relative;
    margin-bottom: 20px;
    padding: 0;
    border-color: var(--ld-border);
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow-sm);
    transition: box-shadow .15s ease, border-color .15s ease;
}
.ld-thumb-grid .thumbnail:hover,
.ld-thumb-grid .thumbnail:focus-within {
    border-color: var(--ld-primary);
    box-shadow: var(--ld-shadow);
}
.ld-thumb-grid .thumbnail > a { display: block; text-decoration: none; }
.ld-thumb-grid .thumbnail img {
    width: 100%;
    height: 210px;
    object-fit: cover;
    object-position: top center;
    background: var(--ld-bg-soft);
    border-bottom: 1px solid var(--ld-border);
    border-radius: var(--ld-radius) var(--ld-radius) 0 0;
}
/* The template gallery stacks every variant's screenshot inside a .crop box
   and relies on overflow to reveal only the first one. That rule lived in
   the Bootstrap-2 styles.css, so keep the behaviour here. */
.ld-thumb-grid .crop {
    height: 210px;
    overflow: hidden;
    border-bottom: 1px solid var(--ld-border);
    border-radius: var(--ld-radius) var(--ld-radius) 0 0;
}
.ld-thumb-grid .crop img { border-bottom: 0; border-radius: 0; }

/* Let an open dropdown paint above the tiles that follow it in the grid. */
.ld-thumb-grid .caption .btn-group.open { position: relative; z-index: 1000; }
.ld-thumb-grid .caption .dropdown-menu {
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow);
}

.ld-thumb-grid .thumbnail .caption { padding: 10px 12px; }
.ld-thumb-grid .thumbnail .caption h4 {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    font-size: 14px;
    line-height: 1.3;
    word-break: break-word;
}
.ld-thumb-grid .thumbnail .caption bull { flex: 0 0 auto; }
.ld-thumb-grid .thumbnail .caption .btn-group { margin-top: 10px; }

/* ==================== 15. SIDEBAR ACTION LIST ==================== */
/* The detail screens carry a stacked list of record actions ("Edit group
   details", "Download as CSV", …). The markup uses Bootstrap 2's
   .nav-list / .nav-header / .divider, none of which survived into
   Bootstrap 3, so the list rendered as unstyled text. */
.ld-action-list { list-style: none; margin: 0; padding: 0; }
.ld-action-list > li > a {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 8px 10px;
    border-radius: var(--ld-radius);
    color: var(--ld-text);
    line-height: 1.4;
    text-decoration: none;
}
.ld-action-list > li > a:hover,
.ld-action-list > li > a:focus {
    background-color: var(--ld-bg-soft);
    color: var(--ld-primary);
    text-decoration: none;
}
.ld-action-list > li > a > i {
    flex: 0 0 16px;
    margin-top: 2px;
    color: var(--ld-primary);
    text-align: center;
}
.ld-action-list > li > a.text-danger,
.ld-action-list > li > a.text-danger > i { color: var(--ld-danger); }
.ld-action-list > li > a.text-danger:hover { background-color: rgba(225, 90, 88, .08); }
.ld-action-list .nav-header {
    padding: 6px 10px;
    color: var(--ld-text-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}
.ld-action-list .divider {
    height: 1px;
    margin: 8px 0;
    overflow: hidden;
    background-color: var(--ld-border);
}
/* The "More/Less options" toggle sits at the foot of the list. */
.ld-action-list .sidebar-padding { padding-top: 4px; }
.ld-action-list .sidebar-padding > a { cursor: pointer; justify-content: flex-end; }

/* A nested list revealed by its parent item (e.g. "Edit contact" opening
   Edit details / Edit contact info / Edit address) — indented under it. */
.ld-action-sublist { margin: 2px 0 2px 14px; }
.ld-action-sublist > li > a { padding-top: 6px; padding-bottom: 6px; font-size: 13px; }

/* ====================== 16. CONTACT MODAL ======================== */
/* The body of a contact modal is loaded over AJAX from
   crm/ajax-contact-modal.html, which still uses the legacy classes
   (.inline-text, .glyphicons, .label, .modal-table, .notes-textarea,
   .log-*) that only the Bootstrap-2 styles.css defines. Styling it here
   means every collection-based page that opens a contact modal — the
   contacts list, a group's detail page — renders it identically. */
.contact-modal .modal-body fieldset { border: 0; margin: 0; padding: 0; }
.contact-modal .inline-text { list-style: none; padding: 0; margin: 0 0 6px; }
.contact-modal .inline-text li { padding: 4px 0; }
.contact-modal .glyphicons i:before,
.contact-modal .halflings i:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    margin-right: 8px;
    color: var(--ld-primary);
}
.contact-modal .glyphicons.phone i:before { content: "\f095"; }   /* phone */
.contact-modal .glyphicons.e-mail i:before { content: "\f0e0"; }  /* envelope */
.contact-modal .halflings.comments i:before { content: "\f075"; color: #999; }  /* comment */
.contact-modal .label {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 7px;
    border-radius: 3px;
    background-color: #999;
    color: var(--ld-white);
    font-size: 11px;
    font-weight: 600;
}
.contact-modal .norecords { font-style: italic; color: var(--ld-text-muted); }
.contact-modal hr { margin: 12px 0; border-top: 1px solid var(--ld-border); }
.contact-modal .modal-table { width: 100%; margin-bottom: 10px; }
.contact-modal .modal-table td { border: 0; padding: 4px 0; }
.contact-modal .log-comments { display: block; }
.contact-modal .log-user,
.contact-modal .log-time { padding-top: 5px; color: var(--ld-text); font-size: 13px; }
.contact-modal .notes-textarea {
    width: 100%;
    margin: 0 0 10px;
    padding: 6px 10px;
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
}

/* ====================== 17. FORM LAYOUT ========================= */
/* An aligned label/control form for the record edit screens (Supplier,
   and any page whose form still uses the Bootstrap-2 control-group /
   control-label / controls markup). Wrap the <form> — or any ancestor of
   the fields — in .ld-form. The label sits to the left of the control on
   desktop and stacks above it on phones. Bare inputs/selects/textareas
   (the forms carry no .form-control class) get a proper control look. */
.ld-form fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.ld-form legend {
    display: block;
    width: 100%;
    margin: 18px 0 16px;
    padding-bottom: 8px;
    border: 0;
    border-bottom: 1px solid var(--ld-border);
    font-size: 16px;
    font-weight: 600;
    color: var(--ld-hard);
}
.ld-form legend:empty { display: none; }
.ld-form .control-group,
.ld-form .controls-group { margin-bottom: 16px; }
.ld-form .control-group::before,
.ld-form .control-group::after,
.ld-form .controls-group::before,
.ld-form .controls-group::after { content: " "; display: table; }
.ld-form .control-group::after,
.ld-form .controls-group::after { clear: both; }

.ld-form .control-label {
    float: left;
    width: 160px;
    padding-top: 7px;
    margin-bottom: 0;
    text-align: right;
    font-weight: 600;
    color: var(--ld-text);
}
/* Mandatory fields are flagged with .required on the label — the asterisk came
   from the Bootstrap-2 styles.css, which the collection base does not load. */
.ld-form .control-label.required::after { content: " *"; color: var(--ld-danger); }
.ld-form .controls { margin-left: 180px; }
.ld-form .controls > input[type="text"],
.ld-form .controls > input[type="number"],
.ld-form .controls > input[type="email"],
.ld-form .controls > input[type="tel"],
.ld-form .controls > input[type="url"],
.ld-form .controls > input[type="date"],
.ld-form .controls > input[type="password"],
.ld-form .controls > textarea,
.ld-form .controls > select {
    display: block;
    width: 100%;
    max-width: 360px;
    padding: 6px 10px;
    color: var(--ld-text);
    background-color: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-sizing: border-box;
}
.ld-form .controls > textarea { height: 80px; min-height: 60px; }
.ld-form .controls > input:focus,
.ld-form .controls > textarea:focus,
.ld-form .controls > select:focus {
    border-color: var(--ld-primary);
    outline: none;
    box-shadow: 0 0 0 3px rgba(84, 195, 187, .2);
}
.ld-form .controls input[type="checkbox"],
.ld-form .controls input[type="radio"] { margin-top: 10px; }
.ld-form .controls .help-block,
.ld-form .controls > p {
    margin: 6px 0 0;
    color: var(--ld-text-muted);
    font-size: 12px;
}
/* Read-only detail rows. .ld-form .control-label carries 7px of top padding
   so it lines up with an <input>'s text; when the "control" is plain text
   with no padding or border of its own, that 7px drops the label below its
   value. Add .ld-form-readonly to the block holding those rows. */
.ld-form-readonly .control-label,
.ld-form .ld-form-readonly .control-label { padding-top: 0; }
.ld-form-readonly .control-group,
.ld-form .ld-form-readonly .control-group { margin-bottom: 10px; }

/* A read-only value box (e.g. the selected supplier address, sitting above
   an Edit button) — replaces the legacy Bootstrap-2 .well. */
.ld-address-box {
    max-width: 360px;
    margin-bottom: 8px;
    padding: 10px 12px;
    background-color: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    color: var(--ld-text);
}

/* Two-column variant. Add .ld-form-grid alongside .ld-form; the fieldset
   that directly holds the fields carries .ld-form-fields and becomes a
   responsive two-up grid with the label stacked above each control. Mark a
   .control-group with .ld-form-full to span the whole row (e.g. Address).
   Below 768px every field drops to a single column. */
.ld-form-grid .ld-form-fields {
    display: flex;
    flex-wrap: wrap;
    gap: 0 24px;
}
.ld-form-grid .ld-form-fields > .control-group,
.ld-form-grid .ld-form-fields > .controls-group {
    flex: 1 1 calc(50% - 12px);
    min-width: 0;
    margin-bottom: 16px;
}
.ld-form-grid .ld-form-fields > .ld-form-full { flex-basis: 100%; }
.ld-form-grid .ld-form-fields > .control-group > .control-label,
.ld-form-grid .ld-form-fields > .controls-group > .control-label {
    display: block;
    float: none;
    width: auto;
    padding-top: 0;
    margin-bottom: 6px;
    text-align: left;
}
.ld-form-grid .ld-form-fields > .control-group > .controls,
.ld-form-grid .ld-form-fields > .controls-group > .controls { margin-left: 0; }
.ld-form-grid .ld-form-fields .controls > input[type="text"],
.ld-form-grid .ld-form-fields .controls > input[type="number"],
.ld-form-grid .ld-form-fields .controls > input[type="email"],
.ld-form-grid .ld-form-fields .controls > input[type="tel"],
.ld-form-grid .ld-form-fields .controls > input[type="url"],
.ld-form-grid .ld-form-fields .controls > input[type="date"],
.ld-form-grid .ld-form-fields .controls > input[type="password"],
.ld-form-grid .ld-form-fields .controls > textarea,
.ld-form-grid .ld-form-fields .controls > select { max-width: 100%; }
@media (max-width: 767px) {
    .ld-form-grid .ld-form-fields > .control-group,
    .ld-form-grid .ld-form-fields > .controls-group { flex-basis: 100%; }
}

/* "Back to …" link above an edit card. */
.ld-back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 14px 0 6px;
    font-weight: 500;
    text-decoration: none;
}
.ld-back-link:hover,
.ld-back-link:focus { text-decoration: none; }

/* The action bar at the foot of the form. */
.ld-form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
    padding: 15px 20px;
    background-color: var(--ld-bg-soft);
    border-top: 1px solid var(--ld-border);
    border-radius: 0 0 var(--ld-radius) var(--ld-radius);
}
.ld-form-actions .ld-actions-spacer { margin-left: auto; }

@media (max-width: 767px) {
    .ld-form .control-label {
        display: block;
        float: none;
        width: auto;
        padding-top: 0;
        margin-bottom: 6px;
        text-align: left;
    }
    .ld-form .controls { margin-left: 0; }
    .ld-form .controls > input,
    .ld-form .controls > textarea,
    .ld-form .controls > select { max-width: 100%; }
}

/* On phones the action buttons stack full-width in reading order; the
   right-align spacer would otherwise shove a wrapped button awkwardly. */
@media (max-width: 575px) {
    .ld-form-actions .btn { flex: 1 1 100%; text-align: center; }
    .ld-form-actions .ld-actions-spacer { margin-left: 0; }
}

/* --- Bootstrap-2 input groups inside .ld-form -------------------------
   Two widgets on the record forms build their own Bootstrap-2 markup and so
   never receive .form-control, leaving them as raw browser controls beside
   properly styled fields:

     * McamDateInput (core/base/forms/widgets.py) renders
       .bootstrap-datepicker-date-widget.input-append and ignores the attrs
       passed to it entirely, so `{% render_field field class+="form-control" %}`
       cannot reach its <input>;
     * the contact typeahead JS injects .input-prepend groups and hides the
       real field behind them.

   Bootstrap 3 dropped .input-append / .input-prepend, so rebuild both as an
   input group here. .ld-form .controls styles only its *direct* input/select
   children, which is why these nested ones were missed. */
.bootstrap-datepicker-date-widget,
.bootstrap-datepicker-datetime-widget,
.input-append,
.input-prepend {
    display: flex;
    width: 100%;
    max-width: 360px;
    margin: 0;
}
.bootstrap-datepicker-date-widget > input,
.bootstrap-datepicker-datetime-widget > input,
.input-append > input,
.input-prepend > input {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    padding: 6px 10px;
    color: var(--ld-text);
    background-color: var(--ld-white);
    border: 1px solid var(--ld-border);
    box-sizing: border-box;
}
.bootstrap-datepicker-date-widget > input:focus,
.bootstrap-datepicker-datetime-widget > input:focus,
.input-append > input:focus,
.input-prepend > input:focus {
    border-color: var(--ld-primary);
    outline: none;
    box-shadow: 0 0 0 3px rgba(84, 195, 187, .2);
    position: relative;
    z-index: 2;
}
/* The add-on sits after the field on .input-append (the datepicker) and
   before it on .input-prepend (the typeahead), so the rounded corners have
   to follow the markup rather than a fixed side. */
.bootstrap-datepicker-date-widget > input,
.bootstrap-datepicker-datetime-widget > input,
.input-append > input { border-radius: var(--ld-radius) 0 0 var(--ld-radius); }
.input-prepend > input { border-radius: 0 var(--ld-radius) var(--ld-radius) 0; }

.bootstrap-datepicker-date-widget > .add-on,
.bootstrap-datepicker-datetime-widget > .add-on,
.input-append > .add-on,
.input-prepend > .add-on {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 0 11px;
    color: var(--ld-text-muted);
    background-color: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
}
.bootstrap-datepicker-date-widget > .add-on,
.bootstrap-datepicker-datetime-widget > .add-on,
.input-append > .add-on {
    border-left: 0;
    border-radius: 0 var(--ld-radius) var(--ld-radius) 0;
    cursor: pointer;
}
.input-prepend > .add-on {
    border-right: 0;
    border-radius: var(--ld-radius) 0 0 var(--ld-radius);
}

/* Both widgets mark their glyph with a Bootstrap-2 sprite class, which the
   collection base does not load — the add-on rendered as an empty grey box.
   Draw the icon with Font Awesome, which the base does load. */
.add-on > i[data-date-icon]::before,
.add-on > i.icon-calendar::before,
.add-on > i.icon-user::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-style: normal;
}
.add-on > i[data-date-icon]::before,
.add-on > i.icon-calendar::before { content: "\f133"; }   /* calendar */
.add-on > i.icon-user::before { content: "\f007"; }        /* user */

/* Once a contact is chosen the typeahead replaces itself with a summary
   line; .inline-help came from the Bootstrap-2 styles.css, so it rendered as
   an unstyled run of text. */
.inline-help {
    display: block;
    max-width: 360px;
    padding: 8px 12px;
    background-color: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    font-weight: 400;
    line-height: 1.5;
}
.inline-help strong { font-weight: 400; }
.inline-help a,
.ld-form .controls a.existing-typeahead-reset,
.ld-form .controls a.existing-delivery-reset { cursor: pointer; }

/* --- Report filter panel ---------------------------------------------
   jobs/filter_form.django.html and jobs/items_filter_form.django.html are
   shared by the six chart reports. They used to build their own Bootstrap-2
   `well span6` card inside a `span10 offset1` row; the panel now collapses
   inside the page's toolbar card, so all these rules have to do is lay the
   fields out. */
.ld-report-filter-grid { display: flex; flex-wrap: wrap; gap: 15px; }
.ld-report-filter-field { flex: 1 1 220px; min-width: 0; margin-bottom: 0; }
.ld-report-filter-field > label,
.ld-report-filter-field > .filter-label {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
    color: var(--ld-text);
}
.ld-report-filter-field .form-control { width: 100%; }
.ld-report-filter-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
    padding-top: 15px;
    border-top: 1px solid var(--ld-border);
}
/* The on/off switch is taller than a text input, so it does not want the
   label spacing the other fields use. */
.ld-report-filter-switch .onoffswitch { margin-top: 2px; }

/* --- YES/NO toggle switch --------------------------------------------
   The .onoffswitch markup (a hidden checkbox + a label with an -inner and
   a -switch span) is used by the report filters, the Add-a-Job form and the
   route screens. Every existing rule for it is scoped: routstyle.css puts
   them all under `.routes` and section 27 here under `.ld-cfs-switch`, so on
   any other page the checkbox is display:none and the two spans are empty
   inline elements — the control rendered as nothing at all. These unscoped
   rules are the base; the scoped blocks still win on specificity, so the
   route and custom-field variants keep their own look. */
.onoffswitch {
    position: relative;
    width: 90px;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
}
.onoffswitch-checkbox { display: none; }
.onoffswitch-label {
    display: block;
    overflow: hidden;
    margin: 0;
    cursor: pointer;
    border: 2px solid var(--ld-border);
    border-radius: 20px;
}
.onoffswitch-inner {
    display: block;
    width: 200%;
    margin-left: -100%;
    transition: margin .3s ease-in 0s;
}
.onoffswitch-inner:before,
.onoffswitch-inner:after {
    display: block;
    float: left;
    width: 50%;
    height: 30px;
    padding: 0;
    line-height: 30px;
    font-size: 13px;
    font-weight: 600;
    color: var(--ld-white);
    box-sizing: border-box;
}
.onoffswitch-inner:before {
    content: "YES";
    padding-left: 10px;
    background-color: var(--ld-primary);
}
.onoffswitch-inner:after {
    content: "NO";
    padding-right: 10px;
    text-align: right;
    background-color: var(--ld-bg-soft);
    color: var(--ld-text-muted);
}
.onoffswitch-switch {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 56px;
    width: 18px;
    margin: 6px;
    background: var(--ld-white);
    border: 2px solid var(--ld-border);
    border-radius: 20px;
    transition: all .3s ease-in 0s;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { margin-left: 0; }
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { right: 0; }

/* The date fields use the same Bootstrap-2 .input-append markup as the record
   forms — see the input-group rules in section 17, which are unscoped, so
   they already cover these. Only the width needs saying here. */
.ld-report-filter-field .input-append { display: flex; width: 100%; margin: 0; }
.ld-report-filter-field .input-append > input {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    border-radius: var(--ld-radius) 0 0 var(--ld-radius);
}
.ld-report-filter-field .input-append > .add-on {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    padding: 0 11px;
    color: var(--ld-text-muted);
    background-color: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
    border-left: 0;
    border-radius: 0 var(--ld-radius) var(--ld-radius) 0;
    cursor: pointer;
}
.ld-report-filter-field .add-on > i[data-date-icon]::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-style: normal;
    content: "\f133";
}

/* The CSV download strip under a report table. */
.ld-report-download { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 16px; }
.ld-report-download .ld-report-download-hint { color: var(--ld-text-muted); font-size: 12px; }

/* --- Date picker popup ------------------------------------------------
   plugins-min.js calls .datetimepicker() on every
   .bootstrap-datepicker-date-widget, and the plugin builds a
   .bootstrap-datetimepicker-widget dropdown. That widget is styled ONLY in
   styles.css / jobstyles.css, which the Bootstrap-2 base loads and the
   collection base does not — so on a converted page the calendar opened as
   an unstyled list of numbers: no month grid, no weekend columns, no
   highlight on the selected day. This is the calendar, rebuilt on the
   design tokens. */
.bootstrap-datetimepicker-widget {
    top: 0;
    left: 0;
    z-index: 1051;
    width: 260px;
    padding: 4px;
    margin-top: 2px;
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .14);
}
/* Do NOT add a `display: block` here. The widget carries .dropdown-menu, so
   Bootstrap keeps it hidden until the plugin calls widget.show(), which sets
   display inline. Forcing block leaves the calendar permanently open at the
   top-left of every page that has a date field. */
.bootstrap-datetimepicker-widget > ul { list-style: none; margin: 0; padding: 0; }
.bootstrap-datetimepicker-widget .datepicker > div { display: none; }
.bootstrap-datetimepicker-widget table { width: 100%; margin: 0; }
.bootstrap-datetimepicker-widget td,
.bootstrap-datetimepicker-widget th {
    width: 32px;
    height: 30px;
    padding: 0;
    text-align: center;
    vertical-align: middle;
    font-size: 13px;
    border: 0;
    border-radius: 4px;
}
/* Month / year header row and the S M T W T F S strip. */
.bootstrap-datetimepicker-widget th {
    font-weight: 600;
    color: var(--ld-hard);
}
.bootstrap-datetimepicker-widget th.dow {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--ld-text-muted);
}
.bootstrap-datetimepicker-widget th.prev,
.bootstrap-datetimepicker-widget th.next,
.bootstrap-datetimepicker-widget th.switch,
.bootstrap-datetimepicker-widget .picker-switch { cursor: pointer; }
.bootstrap-datetimepicker-widget th.prev:hover,
.bootstrap-datetimepicker-widget th.next:hover,
.bootstrap-datetimepicker-widget th.switch:hover { background: var(--ld-bg-soft); }
.bootstrap-datetimepicker-widget th.disabled,
.bootstrap-datetimepicker-widget th.disabled:hover {
    background: none;
    color: var(--ld-text-muted);
    cursor: default;
}
/* Days. .old / .new are the greyed spill-over days from the neighbouring
   months, which is what makes the grid read as a calendar. */
.bootstrap-datetimepicker-widget td.day,
.bootstrap-datetimepicker-widget td.hour,
.bootstrap-datetimepicker-widget td.minute,
.bootstrap-datetimepicker-widget td.second { cursor: pointer; }
.bootstrap-datetimepicker-widget td.day:hover,
.bootstrap-datetimepicker-widget td.hour:hover,
.bootstrap-datetimepicker-widget td.minute:hover,
.bootstrap-datetimepicker-widget td.second:hover { background: var(--ld-bg-soft); }
.bootstrap-datetimepicker-widget td.old,
.bootstrap-datetimepicker-widget td.new { color: var(--ld-text-muted); }
.bootstrap-datetimepicker-widget td.today { font-weight: 700; color: var(--ld-primary); }
.bootstrap-datetimepicker-widget td.active,
.bootstrap-datetimepicker-widget td.active:hover {
    background: var(--ld-primary);
    color: var(--ld-white);
    font-weight: 600;
}
.bootstrap-datetimepicker-widget td.disabled,
.bootstrap-datetimepicker-widget td.disabled:hover {
    background: none;
    color: var(--ld-text-muted);
    cursor: default;
}
/* Month / year / decade pickers use spans rather than a table. */
.bootstrap-datetimepicker-widget td span {
    display: block;
    float: left;
    width: 47px;
    height: 54px;
    margin: 2px 1.5px;
    line-height: 54px;
    cursor: pointer;
    border-radius: 4px;
}
.bootstrap-datetimepicker-widget td span:hover { background: var(--ld-bg-soft); }
.bootstrap-datetimepicker-widget td span.active { background: var(--ld-primary); color: var(--ld-white); }
.bootstrap-datetimepicker-widget td span.old { color: var(--ld-text-muted); }
/* Time picker column, shown when pickTime is on. */
.bootstrap-datetimepicker-widget .timepicker-hour,
.bootstrap-datetimepicker-widget .timepicker-minute,
.bootstrap-datetimepicker-widget .timepicker-second {
    width: 100%;
    font-weight: 600;
    font-size: 1.2em;
    margin: 0;
}
.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator { width: 4px; padding: 0; margin: 0; }

/* ===================== 18. CALENDAR EVENT COLOURS ================= */
/* visitors/calendar.html draws two kinds of event: tasks (from the tasks
   feed) and activities (appointments). The JS tags each event with a class
   and the colours are taken from the tokens here, so the calendar matches
   the rest of the app. These beat FullCalendar's own `.fc-event` colour on
   specificity alone — no !important — which leaves an answered invitation
   free to override its activity with the status colour it sets inline. */
.fc-event.ld-cal-task,
.fc-event.ld-cal-task:hover,
.ui-widget .fc-event.ld-cal-task {
    background-color: var(--ld-info);
    border-color: var(--ld-info);
    /* The info blue is light: dark text reads far better on it than white. */
    color: var(--ld-text);
}
.fc-event.ld-cal-activity,
.fc-event.ld-cal-activity:hover,
.ui-widget .fc-event.ld-cal-activity {
    background-color: var(--ld-hard);
    border-color: var(--ld-hard);
    color: var(--ld-white);
}

/* Day view: eventAfterAllRender injects an "add event" button into every
   other time slat. FullCalendar has already positioned the events by then
   and it measures the grid in pixels, so anything that changes a slat's
   height leaves the events pinned to the old geometry — the hour labels
   slide down while the events stay put, and an 11:15 event ends up drawn
   against the 10am label. (The week view is unaffected because it injects
   nothing.) Take the button out of the flow so each slat keeps its natural
   height and the two layers stay in step. */
.fc-time-grid .fc-slats td { position: relative; }
.fc-time-grid .fc-slats .add-event-btn {
    position: absolute;
    top: 0;
    right: 0;
    padding: 0 3px;
    line-height: inherit;
}

/* Day + week view: a timed event is drawn at its exact length, so a short
   one has no room for its label — a 15-minute task renders 11px tall and
   the text is cut off. Floor every timed event at 20 minutes' worth of
   grid height; anything longer keeps its true height and still grows with
   its duration. FullCalendar positions events with inline top/bottom, and
   min-height wins over `bottom`, so a floored event simply extends down. */
.fc-time-grid-event {
    /* 20 minutes: FullCalendar's slats are 22px per 30 minutes. */
    min-height: 15px;
}
/* That leaves ~13px inside the borders, so the single line .fc-short puts
   the time and title on has to be a little smaller to clear it. */
.fc-time-grid-event.fc-short .fc-content {
    font-size: 11px;
    line-height: 13px;
}

/* Phones. Seven day columns cannot be legible on a 360px screen — squeezed
   flat they leave events about 15px wide. Give the week grid a workable
   width and let it scroll sideways instead; the day and month views fit as
   they are, so they keep filling the screen. */
@media (max-width: 767px) {
    /* Only the grid scrolls — the toolbar (title, day/week/month, today,
       prev/next) stays put where it can always be reached. */
    #calendar .fc-view-container {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    #calendar .fc-agendaWeek-view { min-width: 620px; }
    /* Reclaim width from the hour gutter and keep the header on one line. */
    .fc-axis { font-size: 11px; }
    .fc-toolbar h2 { font-size: 18px; line-height: 1.4; }
    .fc-toolbar .fc-center { float: none; display: block; }
}

/* ====================== 19. CONTACT LOG PANEL ==================== */
/* The read-only "Contact log" list on the contact / company detail pages.
   One entry per row: an icon, the rich-text comment, then the
   "By: … / Posted …" byline (.ld-row-meta, §13). An entry can hold a long
   unbroken string — a pasted URL — so the single cell is given a fixed
   width and breaks the word instead of stretching the table past its card. */
.ld-log-table { table-layout: fixed; width: 100%; max-width: 100%; }
.ld-log-table > tbody > tr > td {
    max-width: 0;
    padding: 8px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
.ld-log-table .log-comments { line-height: 1.4; }
.ld-log-icon { margin-right: 6px; color: var(--ld-text-muted); }
/* The full log list adds a second, narrow column for the Delete button; the
   entry column takes whatever is left of the fixed layout. */
.ld-log-table .ld-log-actions {
    width: 110px;
    max-width: 110px;
    text-align: right;
    white-space: nowrap;
}

/* ================ 20. CONTACT INFO (PHONE / EMAIL) ROWS ========== */
/* crm/contact_detail_fields.html puts a whole entry — dialling code, number,
   type and the add/remove links — inside one .controls, so the §17 rules
   would stack them full-width down the page. Lay them out on a line here
   instead; they wrap on narrow screens. The include is shared with pages
   still on the Bootstrap-2 base, so the fix belongs in CSS, not the markup.
   Wrap the fields in a .contact-detail-group inside an .ld-form. */
.ld-form .contact-detail-group .controls,
.ld-form .contact-detail-group .controls > div {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
/* The "Add phone"/"Add email" buttons append each further entry wrapped in its
   own div, so give those a line to themselves inside the container. */
.ld-form .contact-detail-group .controls > div { flex: 1 1 100%; }

/* Every control in the group — whether it sits directly in .controls or inside
   one of those appended rows — gets the standard control look and sizes itself
   to its content instead of filling the line. */
.ld-form .contact-detail-group .controls input[type="text"],
.ld-form .contact-detail-group .controls input[type="email"],
.ld-form .contact-detail-group .controls input[type="tel"],
.ld-form .contact-detail-group .controls select {
    display: inline-block;
    width: auto;
    min-width: 0;
    margin: 0;
    padding: 6px 10px;
    color: var(--ld-text);
    background-color: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    box-sizing: border-box;
    flex: 1 1 160px;
    max-width: 220px;
}
/* Bootstrap 2's fixed input widths, which Bootstrap 3 dropped. */
.ld-form .contact-detail-group .controls .input-small  { flex: 1 1 110px; max-width: 140px; }
.ld-form .contact-detail-group .controls .input-medium { flex: 1 1 160px; max-width: 220px; }
/* Buttons in the group keep their own size rather than stretching. */
.ld-form .contact-detail-group .controls .btn { flex: 0 0 auto; }

/* ====================== 21. DATE RANGE FILTER ==================== */
/* A "From … To …" pair of date pickers inside one .controls (the report
   download filters). Each picker is a Bootstrap 3 .input-group wrapping the
   legacy .input-append/.add-on markup that bootstrap-datetimepicker needs, so
   the two sit on a line together and drop to their own rows on phones. */
.ld-date-range {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
}
.ld-date-range .ld-date-range-label {
    flex: 0 0 auto;
    margin: 0;
    font-weight: 600;
}
.ld-date-range .input-group {
    flex: 1 1 180px;
    max-width: 220px;
    width: auto;
}
.ld-date-range .input-group .add-on { cursor: pointer; }
@media (max-width: 767px) {
    .ld-date-range .input-group { flex: 1 1 100%; max-width: 100%; }
}
/* A bare date input (no picker widget) sitting in the same row. */
.ld-date-range > input[type="date"],
.ld-date-range > input[type="text"] {
    flex: 1 1 180px;
    width: auto;
    max-width: 220px;
}
@media (max-width: 767px) {
    .ld-date-range > input[type="date"],
    .ld-date-range > input[type="text"] { flex: 1 1 100%; max-width: 100%; }
}

/* ======================== 22. REPORT PAGES ======================= */
/* The custom-field report screens (crm/detail_view_report_*.django.html) draw
   a Google chart and a label/count/percentage table. These rules lived in the
   Bootstrap-2 styles.css, which the collection base does not load. */
.google-chart-report {
    min-height: 300px;
    max-width: 100%;
    overflow-x: auto;              /* the chart is drawn at a fixed pixel width */
    background-color: var(--ld-white);
}
.th-reports-label { width: 60%; }
.th-reports-count,
.th-reports-percentage { width: 15%; }
.table-footer td { font-style: italic; }
.table-footer td.footer-label { text-align: right; }
/* Chart-type menu items are anchors without an href, so they need the cursor. */
.ld-chart-menu > li > a { cursor: pointer; }

/* ===================== 23. CSV UPLOAD SCREENS =================== */
/* The bulk-upload pages hide the real <input type="file"> inside a
   <label class="btn">, so the label is the visible control and the chosen
   file name is written into it by JS. Every one of those pages shipped its
   own copy of this rule in an inline <style>; it lives here now. */
.file-btn {
    position: absolute;
    z-index: -1;
    width: .1px;
    height: .1px;
    opacity: 0;
}
.ld-upload-submit { margin-top: 20px; }

/* Compact rows for the wide upload / lift tables. The old `.tight-table td`
   selector lost to Bootstrap's `.table > tbody > tr > td`, so the padding
   never actually applied — match that specificity. */
.tight-table { font-size: 1em; }
.tight-table > tbody > tr > td { padding: 4px; }

/* An <a> that only toggles a collapse has no href, so it needs the cursor. */
.ld-collapse-link { cursor: pointer; }

/* ==================== 24. CONTACT DETAIL PAGE =================== */
/* crm/contact_view.django.html. These rules replace the two inline <style>
   blocks the page used to carry, plus the bits it lost when it moved off the
   Bootstrap-2 base (styles.css is not loaded by the collection base). */
.pointer { cursor: pointer; }

/* "Contacted N time(s)" chip beside the name, by recency. */
.ld-contacted { margin-left: 4px; }
.ld-contacted-30  { background-color: #337ab7; }
.ld-contacted-60  { background-color: var(--ld-success); }
.ld-contacted-90  { background-color: var(--ld-warning); }
.ld-contacted-old { background-color: var(--ld-danger); }
.label-list { margin-bottom: 6px; }
.label-list .badge { margin-right: 4px; }
.contact-notes { margin-bottom: 0; }
.ld-unsubscribed { margin: 8px 0 0; color: var(--ld-danger); font-weight: 600; }

/* Contact information: one list per method (phones, emails, …) side by side
   on desktop, stacked on phones. The <li> carries a Glyphicons name from the
   database in place of an icon class; that webfont is Bootstrap-2-only, so
   draw a Font Awesome icon for the names the app actually ships and fall back
   to an address-book glyph for anything else. */
.contact-list { display: flex; flex-wrap: wrap; gap: 0 30px; }
.contact-list > .contact-info-list { flex: 1 1 260px; min-width: 0; }
.contact-info-list { list-style: none; margin: 0 0 10px; padding: 0; }
.contact-info-list > li { padding: 4px 0; word-break: break-word; }
.contact-info-list > li > i:first-child {
    display: inline-block;
    width: 18px;
    margin-right: 6px;
    color: var(--ld-primary);
    text-align: center;
}
.contact-info-list > li > i:first-child::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    content: "\f2b9";                                        /* address-book */
}
.contact-info-list > li.phone > i:first-child::before,
.contact-info-list > li.iphone > i:first-child::before { content: "\f095"; }
.contact-info-list > li.e-mail > i:first-child::before,
.contact-info-list > li.envelope > i:first-child::before { content: "\f0e0"; }
.contact-info-list > li.globe > i:first-child::before { content: "\f0ac"; }

/* Address rows: the icon cluster sits right of the address on desktop and
   drops onto its own line on phones rather than crowding the text. */
/* The embedded Google map is a cross-origin iframe on its own compositing
   layer. Stacking order alone does not settle it: on mobile the iframe wins
   the hit test against fixed page chrome painted above it, so taps aimed at
   the floating Actions button landed in the map instead. The only dependable
   cure is to keep the pointer off the iframe — .ld-map-shield covers it and
   takes the tap, and is only lifted while the map is actually in use. */
.ld-map-wrap {
    position: relative;
    z-index: 0;
    margin-bottom: 10px;
}
.ld-map-frame {
    display: block;
    width: 100%;
    max-width: 100%;
    height: 350px;
    border: 0;
}
.ld-map-shield {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding-bottom: 12px;
    background: transparent;
    cursor: pointer;
}
.ld-map-shield-hint {
    padding: 5px 14px;
    border-radius: var(--ld-radius-pill);
    background: rgba(0, 0, 0, .6);
    color: var(--ld-white);
    font-size: 12px;
    line-height: 1.3;
}
/* Map in use: the shield steps aside so panning and zooming work as normal. */
.ld-map-wrap.ld-map-active > .ld-map-shield { display: none; }
.ld-address-actions {
    float: right;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin-left: 12px;
}
.ld-address-actions > i,
.ld-address-actions > a { cursor: pointer; }
.ld-lift-link, .ld-lift-link:hover, .ld-lift-link:focus { color: var(--ld-text); }
.ld-address-links { margin-top: 4px; }
.ld-address-links .label { margin-right: 4px; }
@media (max-width: 767px) {
    .ld-address-actions { float: none; display: flex; margin: 6px 0 0; }
}

/* The link/label chips used by the "Add links" dialog and the address rows. */
.link-name { font-size: 12px; line-height: 16px; }
.remove-link { line-height: 16px; margin-left: 3px; }
.label-link { color: #bbe4f5 !important; text-decoration: none !important; text-shadow: none !important; }
.label-link:hover { color: #000 !important; text-decoration: underline !important; text-shadow: none !important; }

/* "Add links" dialog: one labelled search box per role. */
.ld-address-link-field { margin-bottom: 16px; }
.ld-address-link-field > label { display: block; margin-bottom: 4px; }
.ld-address-link-field .agent-tag:empty,
.ld-address-link-field .landlord-tag:empty,
.ld-address-link-field .tenant-tag:empty { display: none; }
.ld-address-link-field .agent-tag,
.ld-address-link-field .landlord-tag,
.ld-address-link-field .tenant-tag { margin-bottom: 6px; }

/* A row of controls that belong on one line inside a dialog (the Add email /
   Add phone forms), wrapping when there is not room. */
.ld-inline-fields { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ld-inline-fields > .form-control { flex: 1 1 160px; width: auto; min-width: 0; }
.ld-inline-fields > .input-small { flex: 0 1 120px; }
.ld-inline-fields > .input-medium { flex: 0 1 180px; }
.ld-inline-fields > div[id$="Errors"] { flex: 1 1 100%; }

/* Technical-info dialog (crm/snippets/modal_tech_info.html). */
.modal-body .tabbable { padding-top: 0; }
.modal-body .tabbable .nav-tabs { padding-top: 0; margin-bottom: 5px; }
.info_form .modal-body { padding-top: 5px; }
.info_form { font-size: 0.8em; }
.address_info_modal hr { margin-top: 8px; margin-bottom: 8px; }
.address_info_modal table { font-size: 0.8rem !important; }
.address_info_modal table .th { padding: 2px; }

/* ================= 25. CONTACT INFO EDIT ROWS ================== */
/* crm/contact_info_multiple_edit_form.django.html renders one row per phone
   or email: index, optional dialling code, the value, its type, then the
   Delete and default buttons. The widgets carry .form-control (added with
   widget_tweaks) so they are ordinary Bootstrap controls; these rules size
   the columns and let the row wrap instead of overflowing on a phone. */
.contact-info-edit-list { list-style: none; margin: 0; padding: 0; }
.contact-info-edit-list > li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 0;
    border-bottom: 1px solid var(--ld-border);
}
.contact-info-edit-list > li:last-child { border-bottom: 0; }
.ld-info-index {
    flex: 0 0 auto;
    min-width: 16px;
    color: var(--ld-text-muted);
    font-size: 12px;
}
.ld-info-code  { flex: 1 1 170px; max-width: 230px; min-width: 0; }
.ld-info-value { flex: 2 1 200px; max-width: 320px; min-width: 0; }
.ld-info-type  { flex: 1 1 110px; max-width: 140px; min-width: 0; }
.ld-info-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}
.ld-info-actions .btn { cursor: pointer; white-space: nowrap; }
.ld-info-actions .delete-info { color: var(--ld-danger); }
.ld-info-actions .primary-info.is-default { color: var(--ld-primary); }
.contact-info-default-text { font-size: 12px; }
@media (max-width: 767px) {
    .ld-info-code,
    .ld-info-value,
    .ld-info-type { flex: 1 1 100%; max-width: 100%; }
    .ld-info-actions { flex: 1 1 100%; margin-left: 0; }
}

/* ==================== 26. CONTACT ADDRESS LIST ================== */
/* crm/contact_address_list.django.html: one row per address — the address
   (with its Linked / Personal / Invoice badges) on the left, the Link /
   Unlink / Edit buttons on the right, dropping onto their own line on a
   phone. The <li>s used to carry Bootstrap 2's .row, whose negative side
   margins pull the list out of its card under Bootstrap 3. */
.ld-address-list { list-style: none; margin: 0 0 14px; padding: 0; }
.ld-address-list > li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--ld-border);
}
.ld-address-list > li:last-child { border-bottom: 0; }
.ld-address-list .ld-address-text {
    flex: 1 1 240px;
    min-width: 0;
    word-break: break-word;
}
.ld-address-list .ld-address-text .badge { margin-left: 4px; }
.ld-address-list .ld-address-list-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}
.ld-address-list-heading {
    margin: 18px 0 0;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--ld-border);
    font-size: 16px;
    font-weight: 600;
    color: var(--ld-hard);
}
@media (max-width: 767px) {
    .ld-address-list .ld-address-list-actions { flex: 1 1 100%; margin-left: 0; }
}

/* ================ 27. FORMS LOADED INTO A DIALOG ================ */
/* Some dialogs pull a whole <form> — fields plus its own trailing action bar
   — into .modal-body over AJAX; the "Add phone / email / …" dialog on the
   contact detail page is the one that does this. A dialog is too narrow for
   the two-column .ld-form layout, so stack each label above its control, and
   make that trailing action bar read as the dialog's footer. */
.modal .ld-form .control-label {
    display: block;
    /* !important because some of these shared includes still tag the label
       .pull-left, which is itself `float: left !important`. Left floating, a
       short control (a checkbox) rides up beside the label text. */
    float: none !important;
    width: auto;
    padding-top: 0;
    margin-bottom: 6px;
    text-align: left;
}
.modal .ld-form .controls { margin-left: 0; }
/* Checkboxes read as "[x] Label" and need no extra top margin of their own. */
.modal .ld-form .controls .checkbox { margin-top: 0; }
.modal .ld-form .controls .checkbox input[type="checkbox"] { margin-top: 4px; }
.modal .ld-form .controls > input,
.modal .ld-form .controls > select,
.modal .ld-form .controls > textarea { max-width: 100%; }
.modal .ld-form fieldset { margin-bottom: 0; }

/* .modal-body carries 15px of padding, so pull the bar out to the edges. */
.modal-body > form > .ld-form-actions,
.modal-body > div > form > .ld-form-actions {
    margin: 18px -15px -15px;
    border-radius: 0 0 var(--ld-radius) var(--ld-radius);
}

/* Menu items that only open a dialog have no href, so they need the cursor. */
.info-dropdown > li > a { cursor: pointer; }

/* Placeholder shown while a dialog's body is being fetched. */
.modal-body > .loading {
    padding: 24px 0;
    text-align: center;
    color: var(--ld-text-muted);
}
.modal-body > .loading::before {
    display: inline-block;
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 20px;
    content: "\f110";                                            /* spinner */
    animation: ld-spin 1.2s linear infinite;
}
@keyframes ld-spin { to { transform: rotate(360deg); } }

/* ============= 28. OFF-CANVAS ACTIONS SIDEBAR (MOBILE) ========== */
/* A long detail page puts its actions column beside the content on desktop,
   which on a phone means scrolling past everything to reach it. Below 992px
   — the point at which .col-md-* stops floating — the column becomes a
   right-hand drawer opened by a floating button, so the actions are always
   one tap away. Mark the column .ld-sidebar and add the .ld-sidebar-toggle
   button and .ld-sidebar-backdrop after it. */
.ld-sidebar-toggle,
.ld-sidebar-backdrop,
.ld-sidebar-close { display: none; }

@media (max-width: 991px) {
    .ld-sidebar {
        position: fixed;
        top: 0;
        right: 0;
        z-index: 1035;
        width: 300px;
        max-width: 86%;
        height: 100%;
        padding: 52px 15px 24px;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        background: var(--ld-white);
        box-shadow: -2px 0 14px rgba(0, 0, 0, .18);
        transform: translateX(100%);
        transition: transform .25s ease, visibility .25s ease;
    }
    /* A closed drawer is a full-height fixed layer sitting at z-index 1035.
       Translating it off-screen is not enough on its own: sub-pixel rounding,
       a composited transform or an overscrolled page can still leave it
       swallowing taps meant for the floating button underneath. Take it out
       of hit-testing entirely until it is open. */
    .ld-sidebar:not(.open) {
        visibility: hidden;
        pointer-events: none;
    }
    .ld-sidebar.open {
        transform: translateX(0);
        visibility: visible;
        pointer-events: auto;
    }
    /* The card already has the drawer's padding and edge. */
    .ld-sidebar .ld-card {
        margin: 0;
        padding: 0;
        border: 0;
        box-shadow: none;
    }

    .ld-sidebar-close {
        display: block;
        position: absolute;
        top: 10px;
        right: 14px;
        font-size: 26px;
        opacity: .6;
    }

    .ld-sidebar-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        position: fixed;
        right: 16px;
        bottom: 16px;
        /* Above the fixed navbar (1030) and any page chrome, but below the
           drawer's backdrop (1034) so an open drawer covers it. */
        z-index: 1032;
        min-height: 46px;
        padding: 12px 20px;
        border: none;
        border-radius: var(--ld-radius-pill);
        background-color: var(--ld-primary);
        color: var(--ld-white);
        font-weight: 600;
        line-height: 1.2;
        box-shadow: 0 4px 14px rgba(0, 0, 0, .25);
        pointer-events: auto;
        touch-action: manipulation;
        /* Promote the button to its own compositing layer. A composited
           cross-origin iframe (the embedded map) can otherwise capture taps
           aimed at a fixed overlay sitting above it. translateZ on the button
           itself is safe — only a transformed *ancestor* would break
           position: fixed. */
        transform: translateZ(0);
    }
    .ld-sidebar-toggle:hover,
    .ld-sidebar-toggle:focus,
    .ld-sidebar-toggle:active {
        background-color: var(--ld-primary-hover);
        color: var(--ld-white);
        outline: none;
    }
    /* The icon and label must never become the click target's dead zone. */
    .ld-sidebar-toggle > * { pointer-events: none; }

    .ld-sidebar-backdrop.open {
        display: block;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1034;
        background: rgba(0, 0, 0, .5);
    }

    /* Stop the page behind the drawer from scrolling with it. */
    body.ld-sidebar-open { overflow: hidden; }
}

/* ================= 29. PUBLIC CONTACT US FORM ==================== */
/* crm/enquiry_external — the public-facing Contact Us page. Everything is
   prefixed .ldcf- and the page-level tokens are scoped to .ldcf-page, so
   none of it can reach the signed-in pages that also load this file.
   --ldcf-accent is overridden per client from Client.contact_form_colour. */
.ldcf-page {
    --ldcf-accent: var(--ld-primary);
    /* Painted with Client.contact_form_colour when one is set. */
    --ldcf-masthead-bg: #d7dbdb;
    /* Used for anything sitting on the dark details card. Deliberately NOT
       overridden by the client's colour: a client who picks a dark brand
       colour would otherwise make these labels unreadable on the navy. */
    --ldcf-accent-on-dark: #4ecdc0;
    --ldcf-ink: #0f3050;
    --ldcf-canvas: #e9f4f2;
    background: var(--ldcf-canvas);
    color: var(--ld-text);
    font-family: var(--ld-font);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.ldcf-shell {
    width: 100%;
    max-width: 940px;
    margin: 0 auto;
    padding: 0 20px;
}

/* --- masthead --- */
.ldcf-masthead {
    background: var(--ldcf-masthead-bg);
    border-bottom: 3px solid var(--ldcf-accent);
    padding: 18px 0;
    text-align: center;
}

.ldcf-logo-card {
    display: inline-block;
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: 4px;
    padding: 14px 26px;
    min-width: 180px;
}

.ldcf-logo-card img {
    max-height: 60px;
    max-width: 260px;
    width: auto;
    height: auto;
}

.ldcf-logo-name {
    font-size: 14px;
    font-weight: 700;
    color: var(--ldcf-ink);
    margin: 0;
}

/* --- intro --- */
.ldcf-main {
    flex: 1 0 auto;
    padding: 44px 0 56px;
}

.ldcf-eyebrow {
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ld-text-muted);
    margin: 0 0 6px;
}

.ldcf-title {
    font-size: 40px;
    line-height: 1.1;
    font-weight: 700;
    color: var(--ldcf-ink);
    margin: 0 0 14px;
}

.ldcf-lede {
    font-size: 14px;
    line-height: 1.65;
    color: var(--ld-text-muted);
    max-width: 520px;
    margin: 0 0 18px;
}

.ldcf-rule {
    display: block;
    width: 54px;
    height: 3px;
    background: var(--ldcf-accent);
    margin-bottom: 32px;
}

/* --- two column layout --- */
.ldcf-layout {
    display: flex;
    align-items: flex-start;
    gap: 22px;
}

.ldcf-details {
    flex: 0 0 260px;
    background: var(--ld-hard);
    border-radius: 8px;
    padding: 26px 22px;
    color: #dce7ee;
}

.ldcf-form-card {
    flex: 1 1 auto;
    min-width: 0;
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-radius: 8px;
    padding: 26px 26px 22px;
}

/* --- details card --- */
.ldcf-details-name {
    font-size: 17px;
    font-weight: 700;
    color: var(--ld-white);
    margin: 0 0 8px;
    line-height: 1.3;
}

.ldcf-details-tag {
    font-size: 12px;
    line-height: 1.55;
    color: #9fb4c4;
    margin: 0 0 22px;
}

.ldcf-detail {
    padding: 14px 0;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.ldcf-detail-label {
    display: block;
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ldcf-accent-on-dark);
    margin-bottom: 6px;
}

.ldcf-detail-label i { margin-right: 6px; }

.ldcf-detail-value {
    font-size: 13px;
    line-height: 1.55;
    color: var(--ld-white);
    word-wrap: break-word;
}

.ldcf-detail-value a {
    color: var(--ld-white);
    text-decoration: underline;
}

.ldcf-detail-value a:hover,
.ldcf-detail-value a:focus {
    color: var(--ldcf-accent-on-dark);
}

/* --- form --- */
.ldcf-section {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 18px;
}

.ldcf-grid + .ldcf-section { margin-top: 16px; }

.ldcf-step {
    display: inline-block;
    background: var(--ldcf-accent);
    color: var(--ld-white);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.05em;
    border-radius: 3px;
    padding: 3px 6px;
}

.ldcf-section-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--ldcf-ink);
    margin: 0;
}

.ldcf-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0 18px;
}

.ldcf-field {
    flex: 1 1 100%;
    margin-bottom: 16px;
}

.ldcf-field-half {
    flex: 1 1 calc(50% - 9px);
    min-width: 200px;
}

.ldcf-label {
    display: block;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--ld-text);
    margin-bottom: 6px;
}

.ldcf-req {
    color: var(--ld-danger);
    margin-left: 2px;
}

.ldcf-optional {
    color: var(--ld-text-muted);
    font-weight: 400;
    margin-left: 4px;
}

.ldcf-page .ldcf-input,
.ldcf-page select.ldcf-input,
.ldcf-page textarea.ldcf-input {
    display: block;
    width: 100%;
    background: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
    border-radius: 5px;
    padding: 9px 12px;
    font-size: 13.5px;
    color: var(--ld-text);
    box-shadow: none;
    height: auto;
}

.ldcf-page textarea.ldcf-input {
    min-height: 120px;
    resize: vertical;
}

.ldcf-page .ldcf-input:focus {
    outline: none;
    border-color: var(--ldcf-accent);
    background: var(--ld-white);
}

.ldcf-page .ldcf-input::placeholder { color: #9aa9b2; }

.ldcf-help {
    font-size: 11.5px;
    color: var(--ld-text-muted);
    margin: 6px 0 0;
}

.ldcf-field-error .ldcf-input { border-color: var(--ld-danger); }

.ldcf-error {
    font-size: 11.5px;
    color: var(--ld-danger);
    margin: 5px 0 0;
}

/* the dialling-code half of the telephone widget is not collected here */
.ldcf-page #id_telephone_0 { display: none; }

/* Custom (EAV) fields. McamDateInput builds its own markup and ignores the
   attrs passed to it, so a date attribute never receives .ldcf-input - style
   its inner input by container instead so it matches every other field. */
.ldcf-page .bootstrap-datepicker-date-widget,
.ldcf-page .bootstrap-datepicker-datetime-widget { display: block; }

.ldcf-page .bootstrap-datepicker-date-widget input,
.ldcf-page .bootstrap-datepicker-datetime-widget input {
    display: block;
    width: 100%;
    background: var(--ld-bg-soft);
    border: 1px solid var(--ld-border);
    border-radius: 5px;
    padding: 9px 12px;
    font-size: 13.5px;
    color: var(--ld-text);
    box-shadow: none;
    height: auto;
}

.ldcf-page .bootstrap-datepicker-date-widget input:focus,
.ldcf-page .bootstrap-datepicker-datetime-widget input:focus {
    outline: none;
    border-color: var(--ldcf-accent);
    background: var(--ld-white);
}

/* the widget's calendar-icon add-on needs the datepicker JS, which this
   public page does not load - hide it rather than show a dead button */
.ldcf-page .bootstrap-datepicker-date-widget .add-on,
.ldcf-page .bootstrap-datepicker-datetime-widget .add-on { display: none; }

/* checkbox-style custom fields should not stretch to full width */
.ldcf-page .ldcf-field input[type="checkbox"].ldcf-input {
    display: inline-block;
    width: auto;
    height: auto;
}

.ldcf-counter-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.ldcf-counter {
    font-size: 11px;
    color: var(--ld-text-muted);
    font-weight: 400;
}

/* --- captcha + actions --- */
.ldcf-captcha { margin: 4px 0 22px; }

.ldcf-captcha-error {
    display: block;
    font-size: 12px;
    color: var(--ld-danger);
    margin-bottom: 8px;
}

.ldcf-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.ldcf-page .ldcf-btn {
    display: inline-block;
    border-radius: 5px;
    padding: 9px 22px;
    font-size: 13.5px;
    font-weight: 500;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
}

.ldcf-page .ldcf-btn-back {
    background: var(--ld-white);
    border-color: var(--ld-border);
    color: var(--ld-text-muted);
}

.ldcf-page .ldcf-btn-back:hover,
.ldcf-page .ldcf-btn-back:focus {
    border-color: var(--ld-text-muted);
    color: var(--ld-text);
}

.ldcf-page .ldcf-btn-send {
    background: var(--ldcf-accent);
    color: var(--ld-white);
}

.ldcf-page .ldcf-btn-send:hover,
.ldcf-page .ldcf-btn-send:focus {
    filter: brightness(0.93);
    color: var(--ld-white);
}

.ldcf-privacy {
    font-size: 11.5px;
    color: var(--ld-text-muted);
    margin: 16px 0 0;
}

/* --- alerts --- */
.ldcf-alert {
    border-radius: var(--ld-radius);
    padding: 12px 16px;
    font-size: 13px;
    margin-bottom: 20px;
}

.ldcf-alert ul {
    margin: 0;
    padding-left: 18px;
    list-style: disc;
}

.ldcf-alert-error {
    background: #fdecec;
    border: 1px solid #f2c2c4;
    color: #98333a;
}

.ldcf-alert-success {
    background: #e6f6f2;
    border: 1px solid #b6e2d8;
    color: #1d6b5c;
}

/* --- footer --- */
.ldcf-footer {
    flex-shrink: 0;
    background: #dbeae7;
    border-top: 1px solid #c8dcd8;
    padding: 18px 0;
    font-size: 11.5px;
    color: var(--ld-text-muted);
}

.ldcf-footer-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.ldcf-footer a {
    color: var(--ld-text-muted);
    margin-left: 16px;
}

.ldcf-footer a:hover,
.ldcf-footer a:focus { color: var(--ldcf-ink); }

@media (max-width: 767px) {
    .ldcf-layout { flex-direction: column; }

    .ldcf-details {
        flex: 1 1 auto;
        width: 100%;
    }

    .ldcf-title { font-size: 30px; }

    .ldcf-field-half { flex: 1 1 100%; }
}

/* ================ 30. CONTACT FORM SETTINGS MODAL ================ */
/* The settings modal on the enquiries list (crm/enquiry-list). */
.ld-cfs-intro {
    font-size: 13px;
    color: var(--ld-text-muted);
    margin-bottom: 18px;
}

.ld-cfs-row {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid #eee;
}

.ld-cfs-row:last-child { border-bottom: none; }

.ld-cfs-switch {
    flex: 0 0 60px;
    padding-top: 22px;
}

.ld-cfs-field {
    flex: 1 1 auto;
    min-width: 0;
}

.ld-cfs-field label {
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 4px;
}

.ld-cfs-row-off .ld-cfs-field label,
.ld-cfs-row-off .ld-cfs-field .form-control { color: #9aa9b2; }

.ld-cfs-row-off .ld-cfs-field .form-control { background: var(--ld-bg-soft); }

.ld-cfs-colour {
    width: 46px;
    height: 34px;
    padding: 2px;
    border: 1px solid #ccc;
    border-radius: var(--ld-radius);
    background: var(--ld-white);
    cursor: pointer;
}

/* The switch widget's own CSS lives in styles/styles.css, which the enquiries
   list does not load, so the toggle is styled here too. Scoped to the modal so
   it cannot alter switches on pages that do load that stylesheet. */
.ld-cfs-switch .onoffswitch {
    position: relative;
    width: 62px;
    user-select: none;
}

.ld-cfs-switch .onoffswitch-checkbox { display: none !important; }

.ld-cfs-switch .onoffswitch-label {
    display: block;
    overflow: hidden;
    cursor: pointer;
    border: 2px solid #999;
    border-radius: 20px;
    margin: 0;
}

.ld-cfs-switch .onoffswitch-inner {
    display: block;
    width: 200%;
    margin-left: -100%;
    transition: margin 0.3s ease-in 0s;
}

.ld-cfs-switch .onoffswitch-inner:before,
.ld-cfs-switch .onoffswitch-inner:after {
    display: block;
    float: left;
    width: 50%;
    height: 24px;
    padding: 0;
    line-height: 24px;
    font-size: 12px;
    font-weight: 700;
    color: var(--ld-white);
    box-sizing: border-box;
}

.ld-cfs-switch .onoffswitch-inner:before {
    content: "YES";
    padding-left: 6px;
    background-color: var(--ld-primary);
    color: var(--ld-white);
}

.ld-cfs-switch .onoffswitch-inner:after {
    content: "NO";
    padding-right: 10px;
    background-color: #eee;
    color: #999;
    text-align: right;
}

.ld-cfs-switch .onoffswitch-switch {
    display: block;
    width: 15px;
    margin: 4px;
    background: var(--ld-white);
    border: 2px solid #999;
    border-radius: 15px;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 35px;
    transition: all 0.3s ease-in 0s;
}

.ld-cfs-switch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { margin-left: 0; }

.ld-cfs-switch .onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { right: 0; }

/* ============== 31. PUBLIC QUOTE ACCEPTANCE THANK-YOU ============= */
/* quotes/quote_accept — the page a customer lands on after accepting a
   quote from their email. Standalone (no app chrome), so everything is
   prefixed .ldqt- and the tokens are scoped to .ldqt-page. */
.ldqt-page {
    background: var(--ld-bg-soft);
    color: var(--ld-text);
    font-family: var(--ld-font);
    min-height: 100vh;
    padding: 40px 16px;
}

.ldqt-card {
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
    background: var(--ld-white);
    border: 1px solid var(--ld-border);
    border-top: 4px solid var(--ld-primary);
    border-radius: var(--ld-radius);
    box-shadow: var(--ld-shadow);
    padding: 32px;
}

/* --- masthead --- */
.ldqt-logo {
    max-height: 56px;
    max-width: 200px;
    width: auto;
    height: auto;
    display: block;
}

.ldqt-logo-name {
    font-size: 18px;
    font-weight: 700;
    color: var(--ld-hard);
    margin: 0;
}

.ldqt-rule {
    display: block;
    width: 48px;
    height: 3px;
    background: var(--ld-primary);
    margin: 22px 0;
}

/* --- body copy --- */
.ldqt-title {
    font-size: 22px;
    font-weight: 600;
    color: var(--ld-hard);
    margin: 0 0 14px;
    line-height: 1.35;
}

.ldqt-text {
    font-size: 15px;
    line-height: 1.65;
    margin: 0 0 14px;
}

.ldqt-text:last-child { margin-bottom: 0; }

/* --- sign-off --- */
.ldqt-signoff {
    margin-top: 28px;
    padding-top: 20px;
    border-top: 1px solid var(--ld-border);
}

.ldqt-signoff-name {
    font-weight: 600;
    color: var(--ld-hard);
    margin: 0 0 8px;
}

.ldqt-contact {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 14px;
    color: var(--ld-text-muted);
}

.ldqt-contact li { margin-bottom: 4px; }

.ldqt-contact a { color: var(--ld-primary); }

@media (max-width: 575px) {
    .ldqt-page { padding: 20px 12px; }
    .ldqt-card { padding: 22px 18px; }
    .ldqt-title { font-size: 19px; }
    .ldqt-logo { max-height: 44px; max-width: 160px; }
}

/* ============ 32. AI CONTACT-LOG COLLAPSIBLE SECTIONS ============= */
/* Contact-log entries written by the AI assistant mark their two parts with
   <mail_meta> (the header) and <mail_body> (the message). Both are folded away
   behind a labelled arrow so a log list stays scannable;
   crm/includes/ai_log_details.html rewrites each marker as a <details> with
   these classes, supplies the <summary> and wraps the rest in
   .ai-log-content. */
.log-comments details.ai-log-meta,
.log-comments details.ai-log-body {
    display: block;
    margin: 6px 0 0;
    border: 1px solid var(--ld-border);
    border-radius: var(--ld-radius);
    background: var(--ld-bg-soft);
}

.log-comments details.ai-log-meta > summary,
.log-comments details.ai-log-body > summary {
    display: block;              /* Chrome renders summary as list-item */
    list-style: none;            /* hides the Firefox / Chrome triangle */
    padding: 6px 10px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ld-hard);
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.log-comments details.ai-log-meta > summary::-webkit-details-marker,
.log-comments details.ai-log-body > summary::-webkit-details-marker {
    display: none;
}

/* CSS-drawn arrow rather than an icon font, so it survives whatever the
   entry's own markup brings with it. It points right when closed and turns
   down when open. */
.log-comments details.ai-log-meta > summary::before,
.log-comments details.ai-log-body > summary::before {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    margin-right: 8px;
    vertical-align: middle;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    -webkit-transition: -webkit-transform .15s ease;
    transition: transform .15s ease;
}

.log-comments details.ai-log-meta[open] > summary::before,
.log-comments details.ai-log-body[open] > summary::before {
    -webkit-transform: rotate(90deg);
    transform: rotate(90deg);
}

.log-comments details.ai-log-meta > summary:hover,
.log-comments details.ai-log-body > summary:hover {
    color: var(--ld-primary);
}

.log-comments details.ai-log-meta[open] > summary,
.log-comments details.ai-log-body[open] > summary {
    border-bottom: 1px solid var(--ld-border);
}

.log-comments .ai-log-content {
    padding: 8px 10px;
    font-size: 13px;
    line-height: 1.5;
    background: var(--ld-white);
    border-radius: 0 0 var(--ld-radius) var(--ld-radius);
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.log-comments .ai-log-content > *:first-child { margin-top: 0; }
.log-comments .ai-log-content > *:last-child { margin-bottom: 0; }

/* An AI header is a run of "Label: value" lines — keep them tight. */
.log-comments details.ai-log-meta .ai-log-content p { margin-bottom: 4px; }
