/*
  Trunkline office app styles (spec section 4: same brand as the phone app, black header band, gold accent, dark theme
  by default with a light option).

  Colours are DESIGN TOKENS taken from the phone app's Colors.xaml (Gold, the dark paper/surface/ink pairs and the light
  pairs), defined once as CSS variables; nothing below hard-codes a colour. The light theme is selected with
  <html data-theme="light"> (no switch is drawn yet; the variables are ready for one). Quantities use thousands separators in
  the markup, base type is 15px, rows and buttons are at least 40px tall, and every interactive element shows a focus ring.
*/
:root,
:root[data-theme="dark"] {
    /*
      color-scheme tells the browser which scheme its OWN controls should draw in: the calendar glyph of a date input, <select>
      popups, scrollbars, checkbox/radio faces. Without it Chromium draws the light versions (a black calendar glyph on the dark
      surface). It lives beside the tokens so it flips with data-theme exactly as they do; no per-control rule is needed.
    */
    color-scheme: dark;
    --gold: #DBA103;
    --band: #000000;
    --on-gold: #000000;
    --header-h: 92px; /* the rail brand band and every page header share this height so their gold rules line up */
    --paper: #121212;
    --surface: #1E1E1E;
    --ink: #F2F2F2;
    --ink-soft: #A0A0A0;
    --ink-faint: #6E6E6E;
    --border: #333333;
    --border-strong: #5C5C5C; /* outline of a neutral (secondary) button: clearly visible on the dark paper */
    --list-toolbar-h: 56px; /* the sticky chip bar is exactly this tall so group headers can stick directly beneath it */
    /* D12/D13 (desktop UI review 2026-11-01): the room a sticky BOTTOM action bar takes (its 12px padding twice, a 38px button, its 2px
       rule, and the 12px a floating bar keeps from the bottom) plus a gap: toasts sit above it, and focused fields scroll clear of it. */
    --sticky-bar-clearance: 96px;
    --border-soft: #2A2A2A;
    --danger: #DB210F;
    --danger-bg: #3D140F;
    /*
      UC1 option C (Dan, 2026-11-01, stamped Approved in both themes; review D6, D14).
      --danger-text: red TEXT only (field errors, red status words, failed rows). Brand red --danger (#DB210F) is 3.4:1 on a dark
        card, under the 4.5:1 text needs, so words take this lighter red (6.0:1 on a card, 6.7:1 on the page). The brand red stays
        for EDGES and FILLS (the invalid field, the error banner, danger buttons), where 3:1 is enough. Same value as the phone's
        RedTextDark / StockRedTextDark, so a red word reads the same on both apps.
      --field-edge: the resting edge of an input box (.field__input). --border (#333) is 1.3:1 on the dark page, so an empty box was
        almost invisible; this edge is 3.3:1 on the card (the 3:1 a control edge needs).
      Real faint TEXT uses --ink-soft; --ink-faint is kept for DISABLED controls, icons and outlines only (D19).
    */
    --danger-text: #FF6B5B;
    --field-edge: #6E6E6E;
    /*
      --gold-text (approval item 21, Dan 2026-11-01): gold WORDS and gold icons off the band (links, breadcrumbs, the Sign In eyebrow and
        "Forgot password?", "+1 more", dashboard gold words and card icons). Dark: the brand gold itself. Light: #8A6B02 (5.0:1 on white;
        the phone's old TierGoldFg), because brand gold on white is 2.1:1. Gold FILLS, the band, its gold rule, and gold drawn on black
        (the rail wordmark, the header "?", designer tool hovers) keep --gold.
      --band-hover: the hover fill of a button IN the black header band. It is the dark --border-soft value in both themes, because the
        band is black in both (the light --border-soft would be a pale fill under white words).
    */
    --gold-text: #DBA103;
    --band-hover: #2A2A2A;
    --backdrop: rgb(0 0 0 / 60%); /* the dim layer behind a modal dialog and over a loading area (UI kit Dialog / Spinner) */
    --on-band: #FFFFFF;
    --shadow: 0 2px 10px rgb(0 0 0 / 35%);
    /* Photo viewer layers stay near-black in both themes so arbitrary images keep their controls legible. */
    --photo-stage: rgb(0 0 0 / 94%);
    --photo-overlay: rgb(0 0 0 / 88%);
    --photo-control: rgb(0 0 0 / 65%);
    --photo-arrow: rgb(0 0 0 / 60%);
    --photo-control-border: rgb(255 255 255 / 60%);
    --photo-ink: #F2F2F2;
    /* PDF viewer (W17-1): the area around the pages, and the PDF's own paper, which is WHITE in both themes (a PDF assumes white paper and
       PDF.js draws its canvas white), so a page still drawing shows as blank paper, never as a dark hole. */
    --pdf-stage: #2A2A2A;
    --pdf-page: #FFFFFF;
    --neutral-bg: #2C2C2C;
    --neutral-fg: #A0A0A0;

    /*
      Status "tier" colours, taken from the phone app's Colors.xaml (the TierGood/Gold/Warn/Critical pairs) so a status looks the
      same on both apps. The background swaps per theme exactly as on the phone. The phone keeps ONE foreground per tier for both
      themes; on the dark surface that is too dim to read comfortably, so the dark theme uses the brighter brand hue of the same
      tier instead (Green, Gold, Orange, Red from the same palette). Red is reserved for critical states only, as on the phone.
    */
    --tier-good-bg: #1E3311;
    --tier-good-fg: #51DB0F;
    --tier-gold-bg: #3D3110;
    --tier-gold-fg: #DBA103;
    --tier-warn-bg: #3D2610;
    --tier-warn-fg: #DB6F0F;
    --tier-critical-bg: #3D140F;
    --tier-critical-fg: #DB210F;

    /*
      LOCATIONS MAP status colours (stage S6), the map EXCEPTIONS Dan approved: green Complete and red Failed on the map only (decisions
      line 413 item 6; C1 and B7 approved as drawn 2026-10-14, "green Complete and the stage ramp included"). Purpose-specific tokens, used
      ONLY by the Locations map and its legend (a source test pins that); chips and badges everywhere else keep the standing colour rule.
      Defined once for both themes: the map draws on the same street tiles in either theme, and the phone keeps one value for each.
        --map-fail      Failed. ONE token (Dan, Q6: "may revert the map fail colour to orange later"): a revert is this one value.
        --map-complete  Complete (the value drawn on C1 / B7, the phone's QaqcResponseGreen value).
        --map-stage-from / --map-stage-to  the ends of the "QA/QC n of m" ramp: Installed's orange to Complete's colour. A run at
                        n of m is mixed n / m of the way along it (spec 3.4: "steps are interpolated", so a job with more required tests
                        needs no new token); this reproduces C1's drawn steps exactly (1 of 3, 2 of 3).
    */
    --map-fail: #DB210F;
    --map-complete: #51DB0F;
    --map-stage-from: var(--tier-warn-fg);
    --map-stage-to: var(--map-complete);

    /*
      THE EMAIL PICTURE (W12-1, the signature editors' canvas, sheet S1 approved 2026-10-17): the colours of the EMAIL itself, drawn at true
      size inside the editor. They are the server's fixed email colours (Trunkline.Api/Services/Email/Branded/EmailShell.razor and
      SignatureBlock.razor: the light email's grey surround, white card, dark text, grey small lines and sign-off, the grey rule, the
      black band; and the dark email's colours from the shell's dark-mode block), so they are defined ONCE here for both app themes: an
      email does not follow the app's theme, the canvas's own Light / Dark switch chooses which email is drawn. Used only by
      Features/EmailSignature/Design (the canvas); never for the app's own controls.
    */
    --email-outer: #F2F2F2;
    --email-card: #FFFFFF;
    --email-ink: #1A1A1A;
    --email-muted: #666666;
    --email-sign-off: #4D4D4D;
    --email-rule: #D9D9D9;
    --email-band: #000000;
    --email-band-ink: #BDBDBD;
    --email-message-bar: #E6E6E6;
    --email-chip-bg: #E6E6E6;
    --email-dark-outer: #121212;
    --email-dark-card: #1E1E1E;
    --email-dark-ink: #F2F2F2;
    --email-dark-muted: #BDBDBD;
    --email-dark-rule: #444444;
    --email-dark-message-bar: #333333;
    --email-dark-chip-bg: #3A3A3A;
}

:root[data-theme="light"] {
    color-scheme: light;
    --paper: #FFFFFF;
    --surface: #FFFFFF;
    --ink: #000000;
    /* UC1 option C (Dan, 2026-11-01): soft ink moves from #797979 (4.35:1 on white, just under 4.5) to #767676 (4.54:1), and every
       real faint text uses it (D19). --ink-faint stays #ADADAD for disabled controls only. */
    --ink-soft: #767676;
    --ink-faint: #ADADAD;
    --border: #D9D9D9;
    --border-strong: #8E8E8E;
    --border-soft: #EBEBEB;
    --danger-bg: #FAD9D5;
    /* UC1 option C: red TEXT on white is the darker #C4200F (5.9:1; the phone's RedTextLight); an empty field's edge is #8E8E8E (3.3:1). */
    --danger-text: #C4200F;
    --field-edge: #8E8E8E;
    /* Approval item 21: gold WORDS on the light theme's white are #8A6B02 (5.0:1). */
    --gold-text: #8A6B02;
    --backdrop: rgb(0 0 0 / 40%);
    --on-band: #FFFFFF;
    --shadow: 0 2px 10px rgb(0 0 0 / 35%);
    /* Photo viewer layers stay near-black in both themes so arbitrary images keep their controls legible. */
    --photo-stage: rgb(0 0 0 / 94%);
    --photo-overlay: rgb(0 0 0 / 88%);
    --photo-control: rgb(0 0 0 / 65%);
    --photo-arrow: rgb(0 0 0 / 60%);
    --photo-control-border: rgb(255 255 255 / 60%);
    --photo-ink: #F2F2F2;
    --pdf-stage: #EBEBEB;
    --pdf-page: #FFFFFF;
    --neutral-bg: #EDEDED;
    --neutral-fg: #797979;
    --tier-good-bg: #E1F7D6;
    --tier-good-fg: #2E8A0B;
    --tier-gold-bg: #F7ECC8;
    --tier-gold-fg: #8A6B02;
    --tier-warn-bg: #FBE3CC;
    --tier-warn-fg: #B35A0C;
    /* Orange WORDS on the light warn tint: the UC2 option C light orange (Dan, 2026-11-01), ~5.5:1 where #B35A0C is ~4:1. Used by the
       /t clock page reminder, which copies it into its own light block. */
    --tier-warn-text: #8F4709;
    --tier-critical-bg: #FAD9D5;
    --tier-critical-fg: #DB210F;
}

* { box-sizing: border-box; }

html, body {
    height: 100%;
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: "Open Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.45;
}

a { color: var(--gold-text); }
h1 { font-size: 26px; font-weight: 700; margin: 0; }
h2 { font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-soft); margin: 0; }

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* The router moves focus to each page's title (FocusOnNavigate, so a screen reader announces the new page). That is not a
   control the person can type into, so it must not draw a focus box. */
h1:focus, h1:focus-visible { outline: none; }

.eyebrow {
    display: block;
    color: var(--gold-text);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
}

/* ---- shell: left rail + work area ------------------------------------------------------------ */
.shell { display: grid; grid-template-columns: 280px 1fr; height: 100vh; }
.shell__main {
    overflow: auto; background: var(--paper);
    /* D13 (desktop UI review 2026-11-01, Dan: "Approved."): .shell__main is the app's one scroll box, so a field the keyboard focuses (Tab,
       or the D10 first-problem focus) is scrolled into view relative to it. Without this a focused row could stop UNDER the sticky
       ListToolbar (56px) at the top. scroll-padding changes only where the browser stops when it scrolls something INTO view; nothing is
       drawn differently. */
    scroll-padding-top: var(--list-toolbar-h);
}
/* D13: the same at the bottom while a sticky bottom bar is on the page (crew log, inventory select mode, Permission Templates, the QA/QC
   Form Designer's edit bar, the Notifications undo bar), so a focused field never hides under it. */
.shell__main:has(.cl-bar, .inv-bar, .pt__bar, .qf-edit-bar, .undo-bar) { scroll-padding-bottom: var(--sticky-bar-clearance); }

.rail { display: flex; flex-direction: column; background: var(--surface); border-right: 1px solid var(--border); min-height: 0; }
.rail__brand {
    height: var(--header-h); display: flex; align-items: center; padding: 0 18px;
    background: var(--band); border-bottom: 3px solid var(--gold);
}
/* The brand wordmark (gold, Dan 2026-10-01) and the page titles share one size so the two header bands read as a pair. */
.rail__wordmark { color: var(--gold); font-size: 26px; font-weight: 700; letter-spacing: 3px; }
.rail__scroll { flex: 1; overflow: auto; padding: 14px 10px; }
.rail__heading { padding: 6px 10px; }
.rail__list { list-style: none; margin: 0 0 14px; padding: 0; }
.rail__sublist { list-style: none; margin: 2px 0 6px 18px; padding: 0 0 0 8px; border-left: 1px solid var(--border); }
.rail__link--sub { min-height: 36px; font-size: 14px; }
/* A job row = the name (a link to the dashboard) + the chevron (a button that only expands or collapses; Dan, 2026-10-03). */
.rail__job { display: flex; align-items: center; gap: 2px; }
.rail__job-link { flex: 1; min-width: 0; }
.rail__job--open .rail__job-link { font-weight: 600; }
.rail__chevron {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 36px; min-height: 40px; border: 0; border-radius: 10px; background: transparent; color: var(--ink-soft); cursor: pointer;
}
.rail__chevron:hover { background: var(--border-soft); color: var(--ink); }
/* A group header (Setup, Admin) is a button drawn like a rail link: label at the left, chevron at the right, no border or fill of its own. */
.rail__group { display: block; }
.rail__group-toggle { width: 100%; border: 0; background: transparent; font: inherit; text-align: left; cursor: pointer; }
.rail__group-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
/* The unread count beside Notifications: plain gold text, no pill. */
.rail__badge { color: var(--tier-gold-fg); font-weight: 700; font-size: 13px; }
.rail__label { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.rail__note { color: var(--ink-soft); font-size: 12px; padding: 4px 10px; }
.icon { flex: none; vertical-align: middle; }
/* WeatherGlyph (the Pixeden weather art): same footprint as .icon but NOT tinted gold, so it takes the surrounding ink colour. */
.wx-glyph { flex: none; vertical-align: middle; }
.rail__link {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    min-height: 40px; padding: 8px 10px; border-radius: 10px;
    color: var(--ink); text-decoration: none;
}
.rail__link:hover { background: var(--border-soft); }
.rail__link--active { background: var(--paper); box-shadow: inset 3px 0 0 var(--gold); font-weight: 600; }
.rail__empty { color: var(--ink-soft); padding: 4px 10px; margin: 0; }
.rail__footer { border-top: 1px solid var(--border); padding: 12px; display: grid; gap: 10px; }
.rail__user { display: flex; align-items: center; gap: 10px; }
.rail__user-text { display: grid; min-width: 0; }
.rail__user-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__user-role { color: var(--ink-soft); font-size: 12px; }
/* The Help "?" (Dan, 2026-10-15): pushed to the RIGHT end of the name chip's row; the name keeps its ellipsis (min-width 0 above). */
.rail__help { margin-left: auto; flex: none; }
/* The tray holds Log Out alone since Refresh was removed (Dan, 2026-10-15), so the growing button fills the row. */
.rail__tray { display: flex; gap: 8px; }
.rail__tray .btn { flex: 1; }
/* T1 (2026-11-01): Log Out sits inside the kit Tooltip; the wrapper fills the row and the button fills the wrapper, as before. */
.rail__tray > .tooltip { flex: 1; }
.rail__tray > .tooltip > .btn { width: 100%; }

/* The initials chip (D108): gold circle, black text, the person's initials. */
.chip {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: 50%; flex: none;
    background: var(--gold); color: var(--on-gold); font-weight: 700; font-size: 13px;
}

/* ---- pages ----------------------------------------------------------------------------------- */
/* Full width: the header band spans the whole work area and the cards fill it (forms will cap themselves at about 720px). */
.page { padding: 0 28px 28px; }
.page__header {
    height: var(--header-h); margin: 0 -28px 20px; padding: 0 28px;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    background: var(--band); border-bottom: 3px solid var(--gold); color: var(--on-band);
}
.page__header-main { display: flex; flex-direction: column; justify-content: center; min-width: 0; }
.page__header-actions { display: flex; gap: 8px; flex: none; }

/* THE breadcrumb of a page (PageHeader draws it, one per page): "Link Back > Current Location", directly UNDER the header band.
   The band has a 20px bottom margin, so the pull-up keeps the trail close to the title block it belongs to. */
.crumbs { display: flex; align-items: center; gap: 4px; font-size: 13px; color: var(--ink-soft); margin: -8px 0 16px; }
.crumbs__link { color: var(--gold-text); text-decoration: none; }
.crumbs__link:hover { text-decoration: underline; }
.crumbs__current { color: var(--ink-soft); }
.page__subtitle { margin: 4px 0 0; color: var(--ink-soft); font-size: 13px; }

/* ---- narrow-width shell ------------------------------------------------------------------------------------------------------------
   Dan, 2026-11-01, sheets NL1 and NL2 (stamped: option C, and "B. The whole strip, unrolled"); exact words: "the hamburger menu with the
   narrow icon only dropout". AT AND ABOVE 880 px of window width NOTHING CHANGES: every rule that alters the shell sits inside the media
   query below, and the only rule outside it hides the new menu button. BELOW 880 px:
     * the rail leaves its 280 px column and the work area takes the whole width;
     * the header band (and every user of --header-h: the side panel's top, the company logo) shrinks from 92 to 64 px and the page title
       from 26 to 20 px, as drawn on the sheets;
     * a menu button sits at the left end of the band (PageHeader draws it; aria-label only, no visible word);
     * pressing it drops out the SAME rail as a 64 px icon-only strip over the page (.rail--strip, set by Rail.razor while ShellMenuState
       is open): the same icons in the same order, labels hidden from sight but kept for screen readers, the active entry keeping its
       fill and gold bar, the "Jobs" heading drawn as a thin line, the X in the strip's top band, the person chip and its footer at the
       foot. The page does not move (no dim layer: none was asked for).
   WHY 879.98px: ShellMenuState.NarrowMediaQuery is the same string (js/shellMenu.js watches it); 879.98 keeps a fractional zoomed width
   such as 879.5 narrow while exactly 880 stays wide. Theme tokens only; no colour literal, no green. */
.page__menu { display: none; }

@media (max-width: 879.98px) {
    :root, :root[data-theme] { --header-h: 64px; }
    .shell { grid-template-columns: minmax(0, 1fr); }
    .rail { display: none; }
    .page__header h1 { font-size: 20px; }

    /* The band's icon buttons (menu, and the strip's X at the same spot): bare icons like the band's "?" (ScreenHelp), white on the black
       band in both themes, gold on hover; the global gold focus ring marks keyboard focus. The menu button is pulled 16 px into the band's
       28 px margin so it sits where the strip's X appears (the strip is 64 px wide and centres its 40 px X). */
    .page__menu, .rail__close {
        display: inline-flex; align-items: center; justify-content: center; flex: none; min-width: 40px; min-height: 40px; padding: 0;
        border: 0; border-radius: 10px; background: none; color: var(--on-band); cursor: pointer;
    }
    .page__menu { margin-left: -16px; }
    .page__menu:hover, .rail__close:hover { color: var(--gold-text); } /* gold WORDS/glyphs on the page take --gold-text (approval item 21: #8A6B02 in light, the brand gold in dark) */

    /* The dropped-out strip. It is the scroll box itself (band, entries and footer scroll as one column; the band sticks at the top),
       because at 384 px of height the entries do not fit. */
    .rail.rail--strip {
        display: flex; position: fixed; top: 0; bottom: 0; left: 0; z-index: 850; /* above sticky bars and the side panel (800), below dialogs and toasts (900) */
        width: max-content; overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; box-shadow: var(--shadow);
    }
    .rail--strip > .rail__brand, .rail--strip > .rail__scroll, .rail--strip > .rail__footer { width: 64px; box-sizing: border-box; flex: none; }
    .rail--strip .rail__brand { position: sticky; top: 0; z-index: 1; justify-content: center; padding: 0; }
    .rail--strip .rail__wordmark { display: none; }
    .rail--strip .rail__scroll { overflow: visible; padding: 10px; }

    /* Labels, headings, the name beside the chip and Log Out's word: out of sight, still read by a screen reader (as .sr-only). */
    .rail--strip .rail__heading, .rail--strip .rail__label > span, .rail--strip .rail__user-text, .rail--strip .rail__tray-text,
    .rail--strip .rail__empty {
        position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
    }
    /* "a thin line where the Jobs heading was" (the unrolled strip): the company list, when followed by the Jobs heading, closes with a rule. */
    .rail--strip .rail__scroll > .rail__list:not(:last-child) { border-bottom: 1px solid var(--border); padding-bottom: 8px; margin-bottom: 8px; }
    .rail--strip .rail__list { margin: 0; }
    .rail--strip .rail__link { position: relative; justify-content: center; padding: 8px 0; }
    .rail--strip .rail__label { gap: 0; }
    .rail--strip .rail__group-toggle > .icon, .rail--strip .rail__chevron { display: none; }
    .rail--strip .rail__job { display: block; }
    /* A group's or open job's own icons stay grouped under it by the rail's existing thin left line, drawn closer. */
    .rail--strip .rail__sublist { margin: 2px 0 6px 2px; padding: 0 0 0 2px; }
    .rail--strip .rail__note { padding: 4px 0; font-size: 11px; text-align: center; overflow-wrap: anywhere; }
    /* The unread count on the Notifications icon's corner (PROPOSED: the sheets did not draw it), same gold text. */
    .rail--strip .rail__badge { position: absolute; top: 2px; right: 2px; font-size: 11px; line-height: 1; }

    /* The person chip at the foot, then Signed-in Devices, Help and Log Out as icons, one column (they are not drawn on the sheets; they
       stay reachable here because the strip is the only menu below 880 px). */
    .rail--strip .rail__footer { margin-top: auto; padding: 10px 0; justify-items: center; }
    .rail--strip .rail__user { flex-direction: column; gap: 6px; }
    .rail--strip .rail__help { margin-left: 0; }
    .rail--strip .rail__tray .btn { flex: none; min-width: 40px; padding: 8px; }
    .rail--strip .rail__tray .icon { margin-right: 0; }

    /* The kit Tooltip in the strip: the wrapper fills the entry's width, and the bubble is FIXED so the strip's scroll box cannot clip it
       (the kit's own note: an overflow parent clips an absolute bubble). With top left at auto, a fixed box keeps its static place, the
       top of the entry it describes; it is moved to just right of the 64 px strip and centred on the 40 px row, whatever the kit
       placement (so the footer's existing Help and devices tooltips keep their markup unchanged). */
    .rail.rail--strip .tooltip { display: flex; }
    .rail.rail--strip .tooltip > * { flex: 1; }
    .rail.rail--strip .rail__user .tooltip > *, .rail.rail--strip .rail__help .tooltip > *, .rail.rail--strip .rail__tray .tooltip > * { flex: none; }
    .rail.rail--strip .tooltip__bubble { position: fixed; left: 76px; right: auto; top: auto; bottom: auto; transform: none; margin-top: 6px; }
}
.empty, .loading, .notice { color: var(--ink-soft); }
.notice { margin: 0 0 12px; }

/* Cards keep their own height: a taller card (Photos, Inventory) must not stretch its row neighbours to match (Dan, 2026-10-13), so the grid aligns items to the start.
   No empty slot (Dan, 2026-10-14, E1: "Move cards as needed to fit."): with the default sparse placement a two-column card (Inventory)
   that does not fit the last slot of a row wraps and leaves that slot empty; DENSE placement lets a later card fill such a gap, at
   any window width. The cost, accepted by that ruling: a later card may sit before an earlier one in reading order. */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-auto-flow: dense; gap: 14px; align-items: start; }
.card {
    display: grid; align-content: start; gap: 6px; min-height: 110px; padding: 16px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
    color: var(--ink); text-decoration: none;
}
.card:hover { border-color: var(--gold); }
/* Largest (the Daily Report card): the whole row. No minimum height of its own (Dan, 2026-10-14, E1: only as tall as its content). */
.card--large { grid-column: 1 / -1; }
/* Second largest (the Inventory tile, decision D9): two columns wide, as tall as its content. The grid only has two columns when
   the work area (viewport minus the 280px rail and the page padding) holds two 260px columns, about 870px; narrower than that
   the tile takes the one column there is, so it never forces a sideways scroll. */
.card--wide { grid-column: span 2; }
@media (max-width: 880px) { .card--wide { grid-column: span 1; } }
/* Half width (B10, Dan, 2026-10-21: "widen the RFI tile to be half width, do the same for inventory and place them on the same line.").
   The grid above has as many columns as the window holds, often an odd number (3 at 1280px, 5 at 1920px), so no column span is half
   of it. The two half tiles (.card--half) are therefore drawn inside ONE grid item that takes the whole row and splits it into two
   equal columns with the grid's own gap; DashboardLayout decides which tiles go in it. Each column is minmax(0, 1fr) so a long word in
   a tile cannot push its half wider than the other. Under the same 880px breakpoint as the Wide tile (where the grid itself is down to
   one 260px column) the two stack, one above the other, each the full width. The row keeps each tile its own height (align-items:
   start, the rule of the grid above). */
.cards__half-row {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start;
}
@media (max-width: 880px) { .cards__half-row { grid-template-columns: minmax(0, 1fr); } }
.card__title { display: inline-flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; }
.card__title .icon { color: var(--gold-text); }
.card__summary { color: var(--ink-soft); }

/* ---- controls -------------------------------------------------------------------------------- */
/*
  BUTTON HIERARCHY (Dan, 2026-10-03: "what is the thought process behind button coloring?"; the answer is now a rule, used on every
  screen). The colour tells the person how important an action is, so there is at most ONE gold button per view:
    .btn--primary      the ONE main action of the view (Save, Add, Create): solid gold. Never two in one view.
    .btn--secondary    every other action (Cancel, Close, Edit, Refresh): neutral outline, transparent inside.
    .btn--destructive  Deactivate / Remove: GOLD OUTLINE, not a filled button (they are important state changes, not ordinary actions).
    DeleteButton       Delete: neutral secondary outline with a trash icon and visible word; deletion removes only unattached records.
    .btn--icon         a small icon-only button (the pencil / X of an InlineEditCard); give it an aria-label.
  A button with no modifier class is the same as secondary. Nothing is a filled black button any more.
  A DISABLED button (nothing to do yet, for example Save with no changes) is greyed, dashed and not clickable, so it can never be
  mistaken for an available one: pages disable a button until what it does can be done.
*/
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 40px; padding: 8px 16px; border-radius: 10px; border: 1.5px solid var(--border-strong);
    background: transparent; color: var(--ink);
    font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
}
.btn .icon { margin-right: 2px; }
.btn:hover { background: var(--border-soft); }
.btn--primary { background: var(--gold); color: var(--on-gold); border-color: var(--gold); }
.btn--primary:hover { background: var(--gold); filter: brightness(1.1); }
.btn--secondary { background: transparent; color: var(--ink); border-color: var(--border-strong); }
.btn--destructive { background: transparent; color: var(--tier-gold-fg); border-color: var(--gold); }
.btn--destructive:hover { background: var(--tier-gold-bg); }
.btn--icon { min-height: 32px; min-width: 32px; padding: 4px; border-color: transparent; color: var(--ink-soft); }
.btn--icon:hover { color: var(--ink); }
.btn--icon .icon { margin-right: 0; }
.btn--small { min-height: 32px; padding: 2px 12px; font-size: 13px; }
.btn--block { width: 100%; }
/* Disabled: one look for every variant (the pseudo-class outranks the variant classes above). */
.btn:disabled, .btn[aria-disabled="true"] {
    background: var(--neutral-bg); color: var(--ink-faint); border-color: var(--border-soft); border-style: dashed;
    filter: none; cursor: not-allowed;
}
/*
  Buttons IN the black header band (.page__header: Locations' Add Point, Add Run, Measured Run, Required Tests, and the like). The band
  is black in BOTH themes, but the secondary and icon buttons take --ink / --ink-soft, which turn black and grey in the light theme, so
  they vanished on the band (found by the device-theme work, 2026-11-01). In the band they use the band's own ink (--on-band, white) and
  a hover fill that is dark in both themes (--band-hover). The dark theme looks as before (white on black; the same #2A2A2A hover).
  Disabled buttons keep the one disabled look above; the gold primary button is untouched.
*/
.page__header .btn--secondary:not(:disabled):not([aria-disabled="true"]),
.page__header .btn--icon:not(:disabled):not([aria-disabled="true"]) { color: var(--on-band); }
.page__header .btn--secondary:not(:disabled):not([aria-disabled="true"]):hover,
.page__header .btn--icon:not(:disabled):not([aria-disabled="true"]):hover { background: var(--band-hover); color: var(--on-band); }

.field { display: grid; gap: 6px; margin-bottom: 14px; }
/* The label's row (FormField, FieldGroup, DateField): the label, its asterisk and, after the first Save press, the field's message in the
   error red, side by side; the message wraps under the label when the column is narrow (Dan, 2026-10-16: "next to the label it belongs
   to, make them red"). */
.field__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-width: 0; }
/* A fieldset group (FieldGroup): no browser border or padding, the legend spaced like a FormField label. */
.field-group { border: 0; padding: 0; margin: 0 0 14px; min-width: 0; }
.field-group > legend { padding: 0; margin-bottom: 6px; }
.field__label { font-size: 13px; font-weight: 600; }
/* The asterisk of a required field (FormField Required). */
.field__required { color: var(--tier-gold-fg); font-weight: 700; }
.field__row { display: flex; gap: 8px; }
.field__input {
    flex: 1; min-height: 42px; padding: 8px 12px; border-radius: 10px;
    border: 1px solid var(--field-edge); background: var(--surface); color: var(--ink); font: inherit;
}

/* Shared field feedback and two-column form utilities; feature sheets keep only their page layouts. */
.field__input--invalid { border-color: var(--danger); }
.field__error { color: var(--danger-text); font-size: 13px; }
.field__hint { color: var(--ink-soft); font-size: 13px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; align-items: start; }
.form-grid .field--wide { grid-column: 1 / -1; }
/* Narrow-width shell (Dan, 2026-11-01, NL1/NL2): below 880 px of window width the shared two-column form becomes one column (the same
   query as the shell's, ShellMenuState.NarrowMediaQuery). At and above 880 nothing changes. */
@media (max-width: 879.98px) { .form-grid { grid-template-columns: minmax(0, 1fr); } }
.sr-only, .aj__sr, .jd__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Shared table foundations; padding and interaction states remain feature-specific where they differ. */
.table-wrap, .jd__table-wrap, .aj__table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 11px; background: var(--surface); }
table { width: 100%; border-collapse: collapse; }
.table-wrap th, .jd__table th, .aj__table th {
    text-align: left; padding: 10px 14px; font-size: 12px; letter-spacing: .05em; text-transform: uppercase;
    color: var(--ink-soft); border-bottom: 1px solid var(--border);
}
.table-wrap th, .jd__table th { white-space: nowrap; }
.table-wrap td, .jd__table td, .aj__table td { border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
.table-wrap tr:last-child td, .jd__table tr:last-child td, .aj__table tr:last-child td { border-bottom: none; }
.table-wrap tbody tr.row--link { cursor: pointer; }
.table-wrap tbody tr.row--link:hover { background: var(--border-soft); }

/* Shared card and confirmation-dialog shells; feature-only layout/state variants stay scoped. */
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: 11px; padding: 18px; display: grid; gap: 4px; }
.panel > h2 { margin-bottom: 10px; }
.dialog-backdrop { position: fixed; inset: 0; z-index: 900; display: grid; place-items: center; padding: 24px; background: var(--backdrop); }
.dialog { width: 100%; max-width: 480px; padding: 22px; border-radius: 14px; background: var(--surface); border: 1px solid var(--border); }
/* The prompt's title (for Reopen day it is the date) reads as a heading, not the small caps section label h2 uses elsewhere. */
.dialog__title { font-size: 18px; letter-spacing: 0; text-transform: none; color: var(--ink); margin-bottom: 10px; }
.dialog__message { margin: 0 0 14px; color: var(--ink-soft); }
.dialog__buttons { display: flex; justify-content: flex-end; gap: 10px; }

.error-banner {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    margin: 0 0 14px; padding: 10px 14px; border-radius: 10px;
    background: var(--danger-bg); border: 1px solid var(--danger);
}
.error-banner__text { flex: 1; }

/* ---- shared building blocks (see docs/desktop-ui-components.md) ------------------------------- */

/* StatusLabel: plain coloured text, never a pill. */
.status-label { color: var(--ink-soft); font-size: 12px; font-weight: 600; white-space: nowrap; }
.status-label--attention { color: var(--tier-gold-fg); }
.status-label--critical { color: var(--danger-text); }

/*
  ListToolbar: the sticky chip bar. It sticks to the top of the work area (.shell__main is the scroll container) while a list
  scrolls. Its height is FIXED (--list-toolbar-h) and the chips never wrap (they scroll sideways if there are too many), so
  StickyGroupHeader can stick at exactly that offset, directly beneath it. The negative side margins let the bar span the whole
  work area while the page keeps its 28px gutter; the paper background hides rows scrolling underneath.
*/
.list-toolbar {
    position: sticky; top: 0; z-index: 3;
    display: flex; align-items: center; gap: 16px;
    height: var(--list-toolbar-h); margin: 0 -28px; padding: 0 28px;
    background: var(--paper); border-bottom: 1px solid var(--border);
}
.list-toolbar__chips { display: flex; align-items: center; gap: 8px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.list-toolbar__chips::-webkit-scrollbar { display: none; }
.list-toolbar__count { flex: none; color: var(--ink-soft); font-size: 13px; white-space: nowrap; }
.list-toolbar__status { flex: none; }
.list-toolbar__search { flex: 1 1 220px; min-width: 160px; max-width: 360px; margin-left: auto; display: flex; }
.list-toolbar__search .field__input { min-height: 36px; }
/* A filter chip is a toggle button (a chip is not a pill status: it is a control that filters). */
.chip-filter {
    flex: none; min-height: 32px; padding: 4px 14px; border-radius: 16px; border: 1.5px solid var(--border-strong);
    background: transparent; color: var(--ink); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.chip-filter:hover { background: var(--border-soft); }
.chip-filter--selected { background: var(--gold); border-color: var(--gold); color: var(--on-gold); }
.chip-filter--selected:hover { background: var(--gold); filter: brightness(1.1); }

/*
  StickyGroupHeader: each group is its own wrapper and the header is `position: sticky` INSIDE it, so it sticks only while its
  group is on screen and the next group's header pushes it away. `top` leaves room for the chip bar above it (the bar's height is
  fixed). Opaque background so the rows scroll beneath it.
*/
.sticky-group { margin: 0; }
.sticky-group__header {
    position: sticky; top: var(--list-toolbar-h); z-index: 2;
    display: flex; align-items: center; gap: 10px; margin: 0; padding: 8px 0;
    background: var(--paper); border-bottom: 1px solid var(--border-soft);
    font-size: 14px; font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--ink);
}
.sticky-group__count { color: var(--ink-soft); font-weight: 600; font-size: 13px; }
.sticky-group__actions { margin-left: auto; display: inline-flex; gap: 8px; }

/* EmailLink: mail icon then the address, all one link. */
.email-link { display: inline-flex; align-items: center; gap: 6px; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.email-link:hover span { text-decoration: underline; }
.email-link .icon { color: var(--ink-soft); }
.email-link--plain { color: var(--ink-soft); }

/* InlineEditCard: a card with a pencil (view) / X (edit) in its top-right corner. */
.card-edit {
    position: relative; padding: 16px 52px 16px 16px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 11px;
}
.card-edit--editing { border-color: var(--gold); }
/* T1 (2026-11-01): the toggle sits inside the kit Tooltip, so the Tooltip's wrapper takes the corner and the button stays inside it. */
.card-edit > .tooltip { position: absolute; top: 10px; right: 10px; }
.card-edit__title { margin: 0 0 10px; }

/* ---- sign-in --------------------------------------------------------------------------------- */
.login-shell { min-height: 100vh; display: grid; place-items: center; padding: 24px; background: var(--band); }
.login-card {
    width: 100%; max-width: 420px; padding: 28px; border-radius: 14px;
    background: var(--surface); border: 1px solid var(--border);
}
.login-card h1 { margin: 4px 0 18px; overflow-wrap: anywhere; }
.login-card__forgot { margin: 16px 0 0; text-align: center; font-size: 14px; }

#blazor-error-ui {
    display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 1000;
    padding: 10px 20px; background: var(--danger-bg); color: var(--ink);
}
/* T10 (2026-11-01): the close mark is a <button>; it keeps the old look (no button chrome) and gets the global focus ring. */
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 12px; top: 8px; background: none; border: 0; padding: 2px 6px; color: inherit; font: inherit; }

/* ---- toasts: save confirmations that disappear by themselves (ToastHost, one in the layout) ------------------- */
.toast-host {
    position: fixed; right: 20px; bottom: 20px; z-index: 900; /* above sticky bars (z 2 to 5), below the framework error bar (1000) */
    display: flex; flex-direction: column; gap: 8px; max-width: min(420px, calc(100vw - 40px));
    pointer-events: none; /* the stack never blocks the page under it */
}
/* D12 (desktop UI review 2026-11-01, Dan: "Approved"): while a page shows a sticky bottom SAVE / action bar (crew log, inventory select
   mode, Permission Templates, the QA/QC Form Designer), the toast stack rises above it instead of covering its buttons, right where the
   person is looking. It stays bottom-right on every other page, and the toasts stay green (Dan's exception). The Notifications undo bar is
   left out on purpose: it is not a Save bar and sits at the LEFT (max 520px), away from the stack. :has() follows the bar as it comes and
   goes (the inventory bar exists only in select mode), so no page has to tell the toast host anything. */
body:has(.cl-bar, .inv-bar, .pt__bar, .qf-edit-bar) .toast-host { bottom: var(--sticky-bar-clearance); }
.toast {
    color: var(--tier-good-fg); background: var(--surface); border: 1px solid var(--tier-good-fg); border-radius: 8px;
    padding: 10px 14px; overflow-wrap: anywhere; box-shadow: var(--shadow);
}

/* ---- Locations map: the controls and tooltips the map module creates in JS (scoped component CSS cannot reach them) ---- */
.locations-map-control {
    display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; padding: 0; cursor: pointer;
    color: var(--ink); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 4px;
}
.locations-map-control:hover { background: var(--neutral-bg); }
.locations-map-control:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.locations-map-control svg { width: 18px; height: 18px; }
.locations-map-control[hidden] { display: none; }
/* The place-name tooltip on a marker or a line: theme tokens, so it follows light and dark. */
.leaflet-tooltip.locations-tooltip { color: var(--ink); background: var(--surface); border: 1px solid var(--border-strong); box-shadow: var(--shadow); }
.leaflet-tooltip-top.locations-tooltip::before { border-top-color: var(--border-strong); }
.leaflet-tooltip-bottom.locations-tooltip::before { border-bottom-color: var(--border-strong); }
.leaflet-tooltip-left.locations-tooltip::before { border-left-color: var(--border-strong); }
.leaflet-tooltip-right.locations-tooltip::before { border-right-color: var(--border-strong); }
/*
  Stage S6 (C1 approved as drawn): a FAILED run carries a mark near its End Point, a filled --map-fail circle with an exclamation, and a
  permanent label beside it (for example "Failed Cleaning pull · Retest"): a small --map-fail square before the words, so the label reads as the run's
  status and colour is never the only signal.
*/
.locations-fail-mark {
    display: flex; align-items: center; justify-content: center; box-sizing: border-box;
    color: var(--on-band); background: var(--map-fail); border: 1.5px solid var(--paper); border-radius: 50%;
    font-weight: 700; font-size: 12px; line-height: 1;
}
.locations-tooltip__fail-dot {
    display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 1px; background: var(--map-fail); vertical-align: middle;
}
/*
  E8 (2026-10-30): a point's DRAWING MARK, permanently beside its marker while the Drawing Mark layer is on. The same tokens as the name tooltip
  (so it follows light and dark), but compact (small text, no shadow, no pointer arrow): Lighthouse has about 255 points and Dan expects the
  marks to crowd the map, so each label takes as little room as it can and the switch in the legend hides them all. It is a div-icon marker
  (locationsMap.js says why), sized to its text; it never takes a click (the point and the line beneath it keep theirs).
  Map layers (Dan, 2026-10-30): ONE zero-size label box per point (locationsMap.js, pointLabels, says why one and not two), holding the
  point's NAME (while its point type's switch in the layers panel is on) and its DRAWING MARK (E8, while the Drawing Mark switch is on).
  The mark keeps E8's place, just off the marker's upper right (top -20 px; its left is the marker's radius, set by the script), and E8's
  look; the name sits centred ABOVE the point, over the mark's band (top -38 px, moved left by half its own width), so a name never meets
  its neighbour's mark. Both in the name tooltip's tokens (so they follow light and dark), compact (small text, no shadow, no arrow:
  Lighthouse has about 255 points), the mark bold and the name not, so the two read apart. They never take a click.
*/
/* The run design (2026-10-30; RD2 notes 5 and 9): the Split point's small DIAMOND (the round marker's own tokens: --ink-soft fill, --paper
   outline, --gold when selected, --map-fail when failed), and the pipe-name tags along a run, shown only at a close zoom (the map module sets
   locations-map--pipe-tags on the map element from its zoom). */
/* The icon box (Leaflet's own element, positioned by its inline translate3d) is NEVER rotated or scaled: CSS composes `rotate` / `scale`
   with that inline transform, so turning the box turned its map offset too and the diamond drifted off its point (Dan, 2026-11-02). The
   diamond is the inner shape, turned inside the box. */
.leaflet-marker-icon.locations-split { background: none; border: none; }
.locations-split .locations-split__shape {
    box-sizing: border-box; width: 100%; height: 100%; background: var(--ink-soft); border: 2px solid var(--paper);
    transform-origin: center; transform: rotate(45deg) scale(0.8);
}
.locations-split--selected .locations-split__shape { background: var(--gold); }
.locations-split--fail .locations-split__shape { background: var(--map-fail); }
.leaflet-marker-icon.locations-pipes {
    display: none; box-sizing: border-box; height: 16px; padding: 0 4px; white-space: nowrap; pointer-events: none;
    color: var(--ink); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 3px;
    font-size: 10px; font-weight: 600; line-height: 14px; translate: -50% -50%;
}
.locations-map--pipe-tags .leaflet-marker-icon.locations-pipes { display: block; }

.leaflet-marker-icon.locations-labels { width: 0; height: 0; overflow: visible; pointer-events: none; background: none; border: 0; }
.locations-labels .locations-mark,
.locations-labels .locations-name {
    position: absolute; display: block;
    box-sizing: border-box; height: 16px; padding: 0 4px; white-space: nowrap; pointer-events: none;
    color: var(--ink); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 3px;
    font-size: 11px; line-height: 14px;
}
.locations-labels .locations-mark { top: -20px; font-weight: 600; }
.locations-labels .locations-name { top: -38px; left: 0; transform: translateX(-50%); font-weight: 400; }

/* ---- W12-1 (2026-10-17): THE SIGNATURE CANVAS (sheet S1, approved) --------------------------------------------------------------------
   The email drawn at true size inside the General Signature, Automatic Emails and Company Sign-off entries of Setup > Email Templates
   (Features/EmailSignature/Design). Shared here, not in one component's scoped sheet, because three panels draw the same canvas and each
   line inside it is the designer's own editor component (EmailDocumentEditor), whose inner elements a scoped sheet could only reach with
   ::deep from one component. Its colours are the --email-* tokens above (the server's fixed email colours), switched by the canvas's own
   Light / Dark view through the --c-* aliases; the app's tokens are used for the editor marks (the selected line's frame, the toolbar). */
.sig-canvas {
    --c-outer: var(--email-outer);
    --c-card: var(--email-card);
    --c-ink: var(--email-ink);
    --c-muted: var(--email-muted);
    --c-sign-off: var(--email-sign-off);
    --c-rule: var(--email-rule);
    --c-bar: var(--email-message-bar);
    --c-chip: var(--email-chip-bg);
    display: grid; justify-items: center; padding: 14px 0 0; border: 1px solid var(--border); border-radius: 8px;
    background: var(--c-outer); overflow: hidden; max-width: 820px;
}

.sig-canvas--dark {
    --c-outer: var(--email-dark-outer);
    --c-card: var(--email-dark-card);
    --c-ink: var(--email-dark-ink);
    --c-muted: var(--email-dark-muted);
    --c-sign-off: var(--email-dark-muted);
    --c-rule: var(--email-dark-rule);
    --c-bar: var(--email-dark-message-bar);
    --c-chip: var(--email-dark-chip-bg);
}

.sig-canvas__card {
    width: 600px; max-width: 100%; padding: 20px 24px 24px; background: var(--c-card); color: var(--c-ink);
    font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 22px;
}

/* Grey bars stand for the message (S1). */
.sig-canvas__message { display: grid; gap: 8px; margin-bottom: 16px; }

.sig-canvas__message span { display: block; height: 10px; width: 72%; border-radius: 5px; background: var(--c-bar); }

.sig-canvas__message span + span { width: 52%; }

.sig-canvas__band { width: 600px; max-width: 100%; height: 22px; background: var(--email-band); }

.sig-canvas__band--footer { height: auto; padding: 12px 24px; }

/* ---- the signature block, per layout ---- */
.sig-block { display: flex; align-items: stretch; margin-top: 8px; }

.sig-block--logo-below, .sig-block--simple { flex-direction: column; align-items: flex-start; }

.sig-block__lines { min-width: 0; flex: 1; }

.sig-block__bar { width: 4px; flex: none; background: var(--sig-color); }

.sig-block--accent-bar .sig-block__lines { padding-left: 14px; }

.sig-block__bar--thin { width: 3px; margin: 0 12px; }

.sig-block__rule { display: block; width: 48px; height: 3px; margin: 0 0 12px; background: var(--sig-color); }

.sig-block__rule--long { width: 160px; height: 2px; margin: 12px 0; }

/* The logo on its black tile (the company logo is made for black). */
.sig-logo { display: block; flex: none; background: var(--email-band); }

.sig-logo:empty { display: none; }

.sig-logo img { display: block; width: 100%; height: auto; }

.sig-logo--left { width: 100px; align-self: flex-start; margin-top: 2px; }

.sig-logo--below { width: 160px; }

/* ---- the lines ---- */
.sig-lines { display: grid; justify-items: start; }

.sig-line-row { display: flex; align-items: center; gap: 10px; min-height: 20px; }

.sig-line { min-width: 120px; color: var(--c-ink); }

.sig-line--large { font-size: 17px; line-height: 24px; font-weight: 700; }

.sig-line--bold { font-size: 14px; line-height: 20px; font-weight: 700; }

.sig-line--regular { font-size: 14px; line-height: 20px; }

.sig-line--small { font-size: 12px; line-height: 18px; color: var(--c-muted); }

.sig-line__link { text-decoration: underline; }

/* Each line IS the Subject's single-line editor, drawn as email text: no app box, the line's own font; a thin frame shows on the selected line. */
.sig-canvas .sig-line .email-editor { display: block; }

.sig-canvas .sig-line .email-editor .email-editor__surface {
    min-height: 0; padding: 0 4px; border: 1px solid transparent; border-radius: 4px; background: transparent;
    color: inherit; font: inherit; line-height: inherit;
}

.sig-canvas .sig-line .email-editor .email-editor__surface:hover { border-color: var(--border-strong); border-style: dashed; }

.sig-canvas .sig-line-row--selected .sig-line .email-editor .email-editor__surface { border: 1px solid var(--gold); }

.sig-canvas .sig-line .email-editor .email-editor__surface p { margin: 0; min-height: 1em; }

.sig-canvas .sig-line .email-editor .email-editor__field {
    padding: 0 4px; border-radius: 3px; background: var(--c-chip); color: var(--c-ink); font-size: inherit;
}

/* The selected line's small toolbar (app look: it is an editor mark, never in the email). */
.sig-tools {
    display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px; border: 1px solid var(--border);
    border-radius: 8px; background: var(--surface); color: var(--ink); font-family: "Open Sans", "Segoe UI", sans-serif; font-size: 14px;
    font-weight: 400; line-height: 1.4;
}

.sig-tools__style { width: auto; min-width: 110px; min-height: 30px; padding: 2px 8px; }

.sig-tools .btn--icon { min-height: 30px; min-width: 30px; }

/* Add Line: an editor mark under the lines. */
.sig-add-line {
    display: inline-flex; align-items: center; gap: 4px; margin-top: 8px; padding: 2px 10px; border: 1px dashed var(--c-muted);
    border-radius: 6px; background: transparent; color: var(--c-muted); font-family: Arial, Helvetica, sans-serif; font-size: 13px;
    cursor: pointer;
}

.sig-add-line:hover { color: var(--c-ink); border-color: var(--c-ink); }

/* ---- the company sign-off, read-only under its thin rule (S1 mark 8) ---- */
.sig-signoff { margin-top: 24px; }

.sig-signoff__rule { position: relative; height: 1px; background: var(--c-rule); }

.sig-signoff__mark {
    position: absolute; right: 0; top: -9px; padding: 0 0 0 8px; background: var(--c-card); color: var(--c-muted);
    font-size: 11px; line-height: 16px; font-weight: 700;
}

.sig-signoff__text { padding-top: 16px; color: var(--c-sign-off); font-size: 14px; line-height: 20px; white-space: pre-line; }

/* ---- the Trunkline footer line, in the email's black band (Automatic Emails only) ---- */
.sig-footer-line {
    display: block; width: 100%; color: var(--email-band-ink); font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px;
    white-space: pre-line;
}

.sig-footer-line--edit {
    padding: 2px 4px; border: 1px dashed var(--border-strong); border-radius: 4px; background: transparent; resize: vertical;
}

.sig-footer-line--edit:focus-visible { outline: 2px solid var(--gold); border-color: var(--gold); }

/* The editor around the canvas (all three entries): the stacked fields, the canvas's label row with Light / Dark at its right, the actions. */
.sig-editor { display: grid; gap: 18px; }

.sig-canvas-field { display: grid; gap: 8px; }

.sig-canvas-field__head { align-items: center; }

.sig-views { display: inline-flex; gap: 6px; margin-left: auto; }

.sig-editor .actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* The Company Sign-off entry: its lines are edited in place under the rule, in the sign-off's one look (14 px grey). */
.sig-line--sign-off { font-size: 14px; line-height: 20px; color: var(--c-sign-off); }

.sig-signoff--edit { margin-top: 8px; }

.sig-signoff--edit .sig-signoff__text { white-space: normal; }
