/* Carbon ESG's own styles: only what no PO System class covers. Linked in the layout after dark.css.
   A rule that sets a colour has its dark-mode version in this file too (the dashboard's scope colours). */

/* Free text the person typed keeps its line breaks (a record's notes). */
.carbon-notes { white-space: pre-wrap; overflow-wrap: anywhere; }

/* A required field's label gets a red star (the field also has the required attribute). */
.carbon-required::after { content: " *"; color: var(--bs-danger); }

/* A photo's thumbnail in the record page's Photos and Files table, small enough to sit beside the size and date. */
.carbon-thumb { max-width: 6rem; height: auto; }
/* A photo opened in the viewer on a record (record-details.js): whole, within the screen. */
.carbon-photo-full { max-height: 75vh; object-fit: contain; }

/* Dashboard: the three scopes' colours, from the WJ palette (brand.css). Light: blue, navy, coral. Dark: the navy gives
   way to beige so it shows on the dark background. The pie, its legend and the scope tiles share them. */
:root {
  --carbon-scope-1: var(--wj-blue);
  --carbon-scope-2: var(--wj-navy);
  --carbon-scope-3: var(--wj-coral);
}
[data-bs-theme="dark"] {
  --carbon-scope-1: var(--wj-blue-80);
  --carbon-scope-2: var(--wj-beige);
  --carbon-scope-3: var(--wj-coral);
}
.scope-1 { fill: var(--carbon-scope-1); background-color: var(--carbon-scope-1); }
.scope-2 { fill: var(--carbon-scope-2); background-color: var(--carbon-scope-2); }
.scope-3 { fill: var(--carbon-scope-3); background-color: var(--carbon-scope-3); }
.scope-pie { width: 14rem; max-width: 100%; height: auto; }
.scope-slice { stroke: var(--bs-body-bg); stroke-width: 1.5; }
.scope-swatch { display: inline-block; width: .8rem; height: .8rem; border-radius: .15rem; vertical-align: -.05rem; }
.scope-legend li { padding: .15rem 0; }

/* Corporate GHG Summary: the bar charts (BarChart), in the scope colours above. They fill the width up to a limit, so
   their text (in viewBox units) stays readable on a phone and isn't huge on a wide screen. A surface-coloured edge
   separates a stack's scopes, as on the pie. The other colours are the theme's own variables, so dark mode needs no rule
   of its own beyond the scope colours'. */
.corp-chart { display: block; width: 100%; max-width: 40rem; height: auto; overflow: visible; }
.corp-chart text { font-size: 12px; fill: var(--bs-secondary-color); }
/* The months chart runs wider than its viewBox from md up, so its text is set smaller to come out the same size. */
@media (min-width: 768px) { .corp-chart-months text { font-size: 8.5px; } }
.corp-chart .chart-value { fill: var(--bs-body-color); font-weight: 600; }
.corp-chart .chart-baseline { stroke: var(--bs-border-color); stroke-width: 1; }
.corp-chart .chart-bar { stroke: var(--bs-body-bg); stroke-width: 1.5; }
.corp-chart .chart-hit { fill: transparent; }
.corp-chart g:hover .chart-bar { opacity: .8; }
.corp-pie { width: 11rem; }

/* Home: the Power App's five tiles. Phones (below md): full-width navy tiles stacked, an icon and a label each. md and up:
   cards in a grid under the welcome. The Pending Records badge is kept in step by offline.js (data-pending-count). */
.home-links { display: flex; flex-direction: column; gap: .75rem; }
.home-link {
  display: flex; align-items: center; gap: 1rem; padding: 1.5rem 1.25rem; border-radius: .5rem; text-decoration: none;
  background: var(--wj-navy); color: #fff; font-size: 1.25rem; font-weight: 600;
}
.home-link:hover, .home-link:focus-visible { background: var(--wj-navy-80); color: #fff; }
.home-link-icon { flex: none; }
.home-link-label { flex: 1 1 auto; }
.home-link-badge { font-size: .9rem; }
[data-bs-theme="dark"] .home-link { background: var(--wj-dark-bar); border: 1px solid var(--wj-dark-line-strong); color: var(--wj-dark-text); }
[data-bs-theme="dark"] .home-link:hover, [data-bs-theme="dark"] .home-link:focus-visible { background: var(--wj-dark-raised); color: var(--wj-dark-text); }
@media (min-width: 768px) {
  .home-links { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: 1rem; }
  .home-link {
    flex-direction: column; align-items: flex-start; padding: 1.25rem; font-size: 1.05rem;
    background: var(--bs-body-bg); color: var(--bs-body-color); border: 1px solid var(--wj-line); border-top: 3px solid var(--wj-blue);
  }
  .home-link:hover, .home-link:focus-visible { background: var(--wj-blue-10); color: var(--bs-body-color); }
  .home-link-icon { color: var(--wj-blue-ink); }
  .home-link-label { flex: none; }
  [data-bs-theme="dark"] .home-link { background: var(--wj-dark-surface); border-color: var(--wj-dark-line); border-top-color: var(--wj-blue); }
  [data-bs-theme="dark"] .home-link:hover, [data-bs-theme="dark"] .home-link:focus-visible { background: var(--wj-dark-tint-blue); }
  [data-bs-theme="dark"] .home-link-icon { color: var(--wj-dark-link); }
}

/* Home's Needs You cards share a row equally from xl (col-xl). Their one-line, cut-short summaries would otherwise hold a
   card at its full text width and push the next card onto a line of its own. */
.home-needs > * { min-width: 0; }

/* Add New Record's attachments: a small preview of each photo (or the file's type for a PDF) beside its name. The colours
   are the theme's own variables, so dark mode needs no rule of its own. */
.carbon-attach-thumb {
    flex: 0 0 3rem; width: 3rem; height: 3rem; object-fit: cover;
    border: 1px solid var(--bs-border-color); border-radius: .25rem;
}
.carbon-attach-file {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .7rem; font-weight: 600; color: var(--bs-secondary-color); background: var(--bs-tertiary-bg);
}

/* A page's main button (Add Record, Add New Project) runs the full width on a phone, as the Power App's do. */
@media (max-width: 575.98px) {
    .carbon-main-action { flex: 1 1 100%; }
}

/* Form fields that stand out from the page, indoors and on site in daylight (docs/field-styles-plan.md). Meant for the
   PO System's brand.css and dark.css; once they're there and synced, these come out.
   - Border: navy at 60%, 4.4:1 on white (the card line colour it replaces is 1.5:1). Dark: 75% white, 7.9:1. Navy on
     hover. Focus, a validation error and a ticked box keep their own colours.
   - "Increase contrast" turned on in the phone's or computer's settings: navy-80 (7:1) / 80% white.
   - A card holding fields is a shade apart from them. Light: beige behind white fields. Dark: the card lighter than the
     fields (#17406f), as in dark mode a field is otherwise the card's own colour (dark.css).
   - Placeholders, and a select still on its empty choice ("Select Project"), lighter and in italic, so an empty field
     doesn't look filled in. Its open list keeps the normal text colour; only the empty choice in it is lighter. A read-only field has the disabled fill, so it doesn't look editable. */
:is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid) { border-color: #6b7a8f; }
:is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid, :disabled, [readonly]):hover { border-color: var(--wj-navy); }
.card:has(.form-control:not(.form-control-plaintext), .form-select, .form-check-input) { --bs-card-bg: var(--wj-beige-10); }
:is(.form-control, .form-select)::placeholder { color: var(--wj-navy-80); font-style: italic; }
.form-select:has(option[value=""]:checked) { color: var(--wj-navy-80); font-style: italic; }
.form-select option { font-style: normal; color: var(--bs-body-color); }
.form-select option[value=""] { color: var(--wj-navy-80); }
.form-control[readonly]:not(.form-control-plaintext) { background-color: var(--bs-secondary-bg); }
@media (prefers-contrast: more) {
    :is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid) { border-color: var(--wj-navy-80); }
}
[data-bs-theme="dark"] :is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid) { border-color: rgba(230, 235, 242, .75); }
[data-bs-theme="dark"] :is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid, :disabled, [readonly]):hover { border-color: #fff; }
/* dark.css sets the field border after brand.css's focus rule and Bootstrap's validation rules, so in dark mode a focused
   field lost its blue edge and a field with an error its red one. */
[data-bs-theme="dark"] :is(.form-control, .form-select):focus:not(.is-invalid, .is-valid) { border-color: var(--wj-blue); }
[data-bs-theme="dark"] :is(.form-control, .form-select).is-invalid { border-color: var(--bs-form-invalid-border-color); }
[data-bs-theme="dark"] :is(.form-control, .form-select).is-valid { border-color: var(--bs-form-valid-border-color); }
[data-bs-theme="dark"] .card:has(.form-control:not(.form-control-plaintext), .form-select, .form-check-input) { --bs-card-bg: #17406f; }
[data-bs-theme="dark"] :is(.form-control, .form-select)::placeholder { color: rgba(230, 235, 242, .6); }
[data-bs-theme="dark"] .form-select:has(option[value=""]:checked) { color: rgba(230, 235, 242, .6); }
[data-bs-theme="dark"] .form-select option[value=""] { color: rgba(230, 235, 242, .6); }
[data-bs-theme="dark"] .form-control[readonly]:not(.form-control-plaintext) { background-color: rgba(230, 235, 242, .08); border-style: dashed; }
@media (prefers-contrast: more) {
    [data-bs-theme="dark"] :is(.form-control, .form-select, .form-check-input):not(.form-control-plaintext, :focus, :checked, .is-invalid, .is-valid) { border-color: rgba(230, 235, 242, .8); }
}

/* The phone header's online / offline indicator (offline.js), before the app's name: white on the blue bar when online,
   amber when offline. */
.wj-topbar .carbon-net { margin-left: auto; display: inline-flex; align-items: center; gap: .35rem; padding: .15rem .55rem; border-radius: 999px; font-size: .75rem; font-weight: 600; white-space: nowrap; color: var(--wj-navy); background: #fff; }
.wj-topbar .carbon-net + .wj-topbar-app { margin-left: 0; }
.carbon-net-dot { flex: none; width: .55rem; height: .55rem; border-radius: 50%; background: #198754; }
.carbon-net[data-state="offline"] { background: #ffc107; color: var(--wj-navy); }
.carbon-net[data-state="offline"] .carbon-net-dot { background: var(--wj-navy); }
[data-bs-theme="dark"] .wj-topbar .carbon-net { background: rgba(230, 235, 242, .12); color: #e6ebf2; }
[data-bs-theme="dark"] .carbon-net-dot { background: #3ddc84; }
[data-bs-theme="dark"] .carbon-net[data-state="offline"] { background: #ffc107; color: #082145; }
[data-bs-theme="dark"] .carbon-net[data-state="offline"] .carbon-net-dot { background: #082145; }
/* The app's name stays on one line; on a narrow phone there is no room for it beside the logo and the indicator, so it
   gives way (it is in the menu, and on the installed app's icon). */
.wj-topbar-app { white-space: nowrap; }
@media (max-width: 429.98px) { .wj-topbar .carbon-net + .wj-topbar-app { display: none; } }
/* Under 1280px (the sidebar folded away, as in the PO System): messages open under the header bar, not over its menu button. */
@media (max-width: 1279.98px) { .flash-stack { top: 4.25rem; } }

/* The narrowed sidebar (brand.css, .wj-rail) keeps the WJ mark above its button, where the PO System hides the logo:
   white on the blue, blue on the dark bar, as the full logo is. The full logo is too wide for the 72px column. */
.wj-logo-mark { display: none; height: 26px; width: auto; }
@media (min-width: 1280px) {
  .wj-rail .wj-sidebar-top { flex-direction: column; gap: .25rem; }
  .wj-rail .wj-sidebar .wj-brand { display: inline-flex; }
  .wj-rail .wj-sidebar .wj-logo { display: none; }
  .wj-rail .wj-logo-mark-light { display: block; }
  [data-bs-theme="dark"] .wj-rail .wj-logo-mark-light { display: none; }
  [data-bs-theme="dark"] .wj-rail .wj-logo-mark-dark { display: block; }
}

/* The loading screen between pages (site.js, window.CarbonBusy): above everything, the page dimmed behind. */
.carbon-busy { position: fixed; inset: 0; z-index: 2000; display: grid; place-items: center; padding: 1rem; background: rgba(8, 33, 69, .35); }
.carbon-busy[hidden] { display: none; }
.carbon-busy-box { display: flex; align-items: center; gap: .75rem; padding: 1rem 1.5rem; border-radius: var(--bs-border-radius-lg); background: var(--bs-body-bg); color: var(--bs-body-color); box-shadow: var(--bs-box-shadow); font-weight: 600; }
.carbon-busy .spinner-border { flex: none; color: var(--wj-navy); }
[data-bs-theme="dark"] .carbon-busy { background: rgba(0, 0, 0, .55); }
[data-bs-theme="dark"] .carbon-busy .spinner-border { color: var(--wj-blue); }
/* A page's results while a filter, sort or page reloads them (site.js): dimmed, not clickable, with Bootstrap's spinner
   near the top, where the person has just been. The same while the page itself is still coming in: on a slow signal the
   previous page (and its loading screen) goes with the first part of the new one, and the results, last, come in after,
   so until the layout's data-page-end has come the results area spins rather than looking empty, and before the area
   has begun (on Records and the Dashboard the Project filter's 1,400 projects come first) a spinner sits under what
   has. The :has() rules are on their own, as a browser without :has() drops the whole rule it's in. */
[data-list][aria-busy="true"] { position: relative; min-height: 6rem; pointer-events: none; }
[data-list][aria-busy="true"] > * { opacity: .35; transition: opacity .15s; }
[data-list][aria-busy="true"]::after {
    content: ""; position: absolute; top: 2.5rem; left: 50%; width: 2.5rem; height: 2.5rem; margin-left: -1.25rem;
    border: .25em solid var(--wj-navy); border-right-color: transparent; border-radius: 50%; animation: .75s linear infinite spinner-border;
}
[data-bs-theme="dark"] [data-list][aria-busy="true"]::after { border-color: var(--wj-blue); border-right-color: transparent; }
main:not(:has(> [data-page-end])) > [data-list] { position: relative; min-height: 6rem; pointer-events: none; }
main:not(:has(> [data-page-end])) > [data-list] > * { opacity: .35; }
main:not(:has(> [data-page-end])) > [data-list]::after {
    content: ""; position: absolute; top: 2.5rem; left: 50%; width: 2.5rem; height: 2.5rem; margin-left: -1.25rem;
    border: .25em solid var(--wj-navy); border-right-color: transparent; border-radius: 50%; animation: .75s linear infinite spinner-border;
}
[data-bs-theme="dark"] main:not(:has(> [data-page-end])) > [data-list]::after { border-color: var(--wj-blue); border-right-color: transparent; }
main:not(:has(> [data-page-end], > [data-list]))::after {
    content: ""; display: block; width: 2.5rem; height: 2.5rem; margin: 2rem auto;
    border: .25em solid var(--wj-navy); border-right-color: transparent; border-radius: 50%; animation: .75s linear infinite spinner-border;
}
[data-bs-theme="dark"] main:not(:has(> [data-page-end], > [data-list]))::after { border-color: var(--wj-blue); border-right-color: transparent; }

/* The Records list stacked up to 1,200 px, not only on phones (site.css's table-stack, which is the PO System's and isn't
   edited here, stops at 768 px): a laptop zoomed to 125% or 150% otherwise gets a 12-column table wider than the screen,
   with Approve and Reject off its right-hand edge (the walkthrough of 29 October). The same rules as table-stack, for
   768 to 1,199 px; colours come from Bootstrap's variables, so dark mode needs nothing of its own. */
@media (min-width: 768px) and (max-width: 1199.98px) {
    .table-stack-wide > thead { display: none; }
    .table-stack-wide, .table-stack-wide > tbody, .table-stack-wide > tbody > tr, .table-stack-wide > tbody > tr > td { display: block; width: 100%; }
    .table-stack-wide > tbody > tr { border-bottom: 1px solid var(--bs-border-color); padding: .4rem 0; }
    .table-stack-wide > tbody > tr > td { border: 0; padding: .15rem .75rem; text-align: left; }
    .table-stack-wide > tbody > tr > td:empty { display: none; }
    .table-stack-wide > tbody > tr > td[data-label] { position: relative; padding-left: calc(30% + .75rem); }
    .table-stack-wide > tbody > tr > td[data-label]::before {
        content: attr(data-label); position: absolute; left: .75rem; width: 30%; color: var(--bs-secondary-color); font-size: .875em;
        padding-top: .1rem;
    }
    .table-stack-wide > tbody > tr > td.text-end { text-align: left !important; }
    .table-stack-wide .text-nowrap { white-space: normal !important; }
}

/* From 1,200 px the Records list is a table, which on a laptop (1366 or 1440 px, less the sidebar) is still wider than
   the page and scrolls sideways: Approve and Reject, its last column, stay on screen at its right-hand edge (the
   dogfood of 30 October). The page's background covers what scrolls under them: in dark mode the PO System's table
   cells are transparent (dark.css), so Status, Data Quality and Entered By showed through at 1,300 px (30 October).
   Bootstrap draws a row's hover over the background (an inset shadow), so the hover still shows. */
@media (min-width: 1200px) {
    .table-stack-wide .records-actions {
        position: sticky; right: 0; z-index: 1; border-left: 1px solid var(--bs-border-color); background-color: var(--bs-body-bg);
    }
}

/* Corporate GHG Summary: the Scope 3 by Category bars, each with its full name on a line above it. Held to about the
   width of half a laptop screen, so the names come out near the size of the text round them rather than large on a
   tablet or a zoomed laptop; on a phone the chart is narrower, so its text is set larger to stay readable. Colours as
   the other charts', from the theme. */
.corp-chart-cats { max-width: 30rem; }
@media (max-width: 575.98px) { .corp-chart-cats text { font-size: 15px; } }

/* A factor set's page: Change, Fill In and saving land on the form, Needs a Figure or the row (#factor-form,
   #needs-figure, #factor-<id>); the margin keeps them clear of the top bar on a narrow or zoomed screen. */
#factor-form, #needs-figure, [data-test="factors"] tr[id^="factor-"] { scroll-margin-top: 5rem; }

/* Report tables that repeat with the same columns (a client return's tabs) or set figures side by side (the corporate
   months): the same column widths every time, so each column sits in the same place from one table to the next instead
   of each table sizing itself to its own words. From md up; below that they stack (table-stack). The widths come from
   the header cells, as a fixed layout takes them from the first row. */
@media (min-width: 768px) {
    .carbon-return-table, .carbon-months-table { table-layout: fixed; }
    .carbon-return-table > thead > tr > th:nth-child(1) { width: 5%; }   /* Row */
    .carbon-return-table > thead > tr > th:nth-child(2) { width: 17%; }  /* Item */
    .carbon-return-table > thead > tr > th:nth-child(3) { width: 15%; }  /* Type */
    .carbon-return-table > thead > tr > th:nth-child(4) { width: 8%; }   /* Quantity */
    .carbon-return-table > thead > tr > th:nth-child(5) { width: 7%; }   /* Unit */
    .carbon-return-table > thead > tr > th:nth-child(6) { width: 8%; }   /* Distance (km) */
    .carbon-return-table > thead > tr > th:nth-child(7) { width: 7%; }   /* Vehicle */
    .carbon-return-table > thead > tr > th:nth-child(8) { width: 15%; }  /* Notes */
    .carbon-return-table > thead > tr > th:nth-child(9),
    .carbon-return-table > thead > tr > th:nth-child(10) { width: 9%; }  /* App and Template tCO2e */
    .carbon-return-table td { overflow-wrap: anywhere; }
    .carbon-months-table > thead > tr > th:first-child { width: 16%; }
    .carbon-months-table > thead > tr > th:not(:first-child) { width: 21%; }
    /* Right-aligned figures side by side: a gap before each, so a long heading doesn't run into the one before it, and
       a heading that still doesn't fit wraps inside its column. */
    .carbon-months-table .num { padding-left: 1.5rem; }
    .carbon-months-table > thead > tr > th { white-space: normal; }
}
