/* =============================================================================
   home-landing-enhance.css — the six components added to the landing page
   -----------------------------------------------------------------------------
   WHY THIS IS A SEPARATE SHEET AND NOT AN EDIT TO home-landing.css.
   That file is 1,144 lines and it already carries the small-screen, reduced-
   motion, forced-colours and print behaviour of every component on the page.
   Restyling six sections inside it is how that work gets damaged by accident.
   This sheet only ADDS, and re-points nothing that already exists:

     1. .lp-hero__official  — the "official service of MDE" trust line
     2. .lp-rail            — the on-this-page jump menu, styled as a tab strip
                              and STICKY, so it is still on screen after a jump
     3. .lp-door            — "Which one is mine?", the sign-in decision helper
     4. .lp-legend          — the key to the thirteen duty tags in the flow
     5. anchor offsets      — scroll-margin so a jumped-to heading lands below
                              the sticky menu instead of underneath it
     6. .lp-totop           — the floating "Jump menu" button that returns the
                              reader to the strip on narrow screens, where it
                              does not stick (see the 40rem block)

   IT IS LOADED LAST, from @section Styles in Views/Home/Index.cshtml, which is
   rendered after every site sheet. Nothing here needs !important, and nothing
   here should acquire it: if a declaration does not win, the selector is wrong.

   TOKENS ONLY, AND ONLY TOKENS THAT EXIST. An undefined var() does not fall
   back — the whole declaration is dropped, silently. Every custom property used
   below is defined in tokens.css or brand.css. The two hard-coded lengths (the
   scroll offsets) are measured against md-gov.css and say so at the point of use.

   Equal-height form cards are NOT here: .lp-form is already a flex column and
   .lp-form__status already pins itself with `margin: auto 0 0`
   (home-landing.css:409, 489). Restating it here would be a second owner of the
   same decision.
   ============================================================================= */

/* ------------------------------------------------- 1. hero: official service */

/*  Sits on the hero's dark band, above the <h1>, so it is read first. Quieter
    than the lede: it is provenance, not the offer. The colour is white at .82
    rather than a token because the whole hero is a light-on-dark inversion —
    every other hero rule in home-landing.css does the same thing for the same
    reason (see .lp-hero__lede at .92 and .lp-hero__agency span at .68). */
.lp-hero__official {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    font-size: var(--fs-3xs);
    font-weight: var(--fw-medium);
    line-height: var(--lh-snug);
    letter-spacing: .01em;
    color: rgba(255, 255, 255, .82);
    margin: 0 0 var(--sp-1);
    max-width: 52ch;
}

/*  The shield is decoration beside text that already says it, so it is
    aria-hidden in the markup and merely sized here. It must not grow with a
    long line's wrap, hence flex: 0 0 auto. */
.lp-hero__official > i {
    flex: 0 0 auto;
    font-size: .9em;
    opacity: .9;
}

/* ------------------------------------------------------ 2. on-this-page rail */

/*  A one-line answer to "is the thing I came for even on this page", read once
    on arrival. The page is long by design — nine forms, five stages, thirteen
    obligations — and the rail is what stops that length from reading as a wall.

    IT NOW STICKS, AND THE OBSTACLE THAT PREVIOUSLY BLOCKED IT IS MEASURABLY
    GONE. The earlier decision not to stick rested on md-gov.css shipping
    #header_container and .mdgov-entNav as position:fixed (50px tall, 60px from
    768px up) at z-index 1000: a rail pinned to top:0 would either hide under
    that bar or float a guessed 50px below one that is not there. Checked against
    the SERVED page rather than the stylesheet — neither element is emitted by
    the layout this view uses, so top:0 is the real top of the viewport here and
    no guess is being made. That was the condition the old comment set for making
    this change ("against a real header, with a measured offset"), and it is met.

    WHY IT MATTERS: a jump menu that scrolls away answers "is it here" once, then
    makes the second question a scroll back to the top. Staying on screen makes
    every other section one click away — which is the whole reason to style it as
    a tab strip rather than a row of pills.

    IF THE STATE HEADER IS EVER ADDED TO THIS LAYOUT, exactly two numbers move
    together: this `top`, and --lp-rail-h below (the anchor offset). Nothing else
    depends on the rail's height.

    STILL NOT role="tablist", AND THAT IS DELIBERATE. It looks like tabs and is
    styled as tabs, but real tabs own panels and manage focus with arrow keys;
    these are anchors that move the page. Announcing them as tabs would promise a
    keyboard contract this markup does not honour, so the <nav> stays a <nav> and
    the links stay links. The tab appearance is presentation, not semantics. */
.lp-rail {
    position: sticky;
    top: 0;
    /*  Above the page's own bands, which establish no stacking context in this
        range. Deliberately far below md-gov.css's 1000, so if that fixed chrome
        ever IS rendered the state bar still wins and this tucks under it rather
        than covering it. */
    z-index: 5;

    /*  FULL-WIDTH BAND, CENTRED CONTENT. The band must be opaque edge to edge or
        the page's content shows through beside the centred list as it scrolls
        underneath. So the width constraint moves off this element and onto the
        list, and the bottom rule moves here — it is now the band's edge, which
        is also what the tabs sit on. */
    background: var(--c-paper);
    border-bottom: var(--border-1);
}

/*  --lp-rail-h IS THE MEASURED HEIGHT OF THE STICKY BAND: 12px top padding +
    the 44px tab floor + 12px bottom padding + the 1px band edge = 69px.

    ON :root, NOT ON THE RAIL, and that is not tidiness. The anchor offsets below
    are set on #forms, #how and their siblings, which are NOT descendants of the
    rail — a custom property only inherits downwards, so one declared on the rail
    would resolve to nothing there and `calc()` would drop the whole declaration
    silently. Declared once at the root, both ends of the relationship can see it. */
:root {
    --lp-rail-h: 69px;
}

.lp-rail__list {
    display: flex;
    /*  WRAP, NEVER SCROLL. A horizontally scrolling strip hides its own last
        item on a phone, and the last items here are Help and Who it's for —
        the two a lost visitor needs most. Wrapping costs a second line. */
    flex-wrap: wrap;
    /*  Tabs sit shoulder to shoulder, so the gap closes from --sp-1 to 2px: a
        tab strip reads as one control, and 8px gutters read as six separate
        buttons. The 44px target is untouched — it is the padding that carries
        the comfort, never the gap. */
    gap: 2px;
    list-style: none;
    max-width: var(--maxw-page);
    margin: 0 auto;
    padding: var(--sp-15) var(--sp-3);
}

/*  A TAB, NOT A PILL. Square top corners, no side or top border, and a 3px
    bottom edge that is the whole indicator — the shape the eye already reads as
    "one of a set of destinations" rather than six unrelated buttons.

    THE 3px EDGE IS TRANSPARENT AT REST AND NEVER MISSING. Reserving the border
    at rest instead of adding it on hover is what stops the label shifting 3px
    the moment a pointer lands on it; only the COLOUR changes. This is the same
    reason the underline is added rather than the border grown.

    44px MINIMUM TARGET, built from padding rather than a height, so the tab
    still grows if the label wraps. min-height carries the floor for the short
    labels; the padding is what actually makes it comfortable. */
.lp-rail__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: .5rem 1rem;
    font-size: var(--fs-3xs);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-tight);
    color: var(--c-primary-dark);
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.lp-rail__link:hover {
    background: var(--c-primary-lighter);
    border-bottom-color: var(--c-primary);
    color: var(--c-primary-darker);
    /*  The underline is added on hover rather than removed: these are links,
        and a tab that only changes colour is a weaker affordance than a tab
        that also underlines. */
    text-decoration: underline;
}

/*  THE SECTION YOU ARE ON CANNOT BE MARKED, and pretending otherwise was the
    old comment's point: an accurate "current tab" needs a scroll observer, and
    this page loads no script for its own content. :target is not a substitute —
    it marks the section that was CLICKED, which stops being true the moment the
    reader scrolls on, so a tab lit by it would go on asserting a location the
    reader has left. A strip that does not claim to know where you are is honest;
    one that claims wrongly is worse than silent. */

/*  box-shadow, NOT outline. --focus-ring is a two-layer shadow (a light halo
    inside a dark ring) so it stays visible on both the paper and the primary
    backgrounds; assigning it to `outline` would be an invalid value and the
    focus indicator would disappear entirely. */
.lp-rail__link:focus-visible {
    box-shadow: var(--focus-ring);
    border-bottom-color: var(--c-primary-dark);
    outline: none;
}

/* --------------------------------------------- 5. anchor offsets for the rail

   THE RAIL'S TARGETS MUST NOT LAND UNDER THE RAIL ITSELF. This is the whole of
   the instruction "have the jump menu clicked show content but see jump menu":
   a sticky band and a plain #anchor fight each other, because the browser aligns
   the section's top edge with the viewport's top edge — which is now BEHIND the
   band. Without this offset every tab would appear to jump to the wrong place,
   the heading hidden under the strip that had just been clicked. The reader would
   read that as a broken link, not as a covered one.

   NOW DERIVED, NOT RESTATED. The offset is the band's measured height plus 14px
   of breathing room, so the heading clears the strip's edge instead of sitting
   flush against it. Previously these were two hard-coded lengths (64px, and 74px
   from 48em) clearing the FIXED STATE HEADER, which — measured against the served
   page — this layout does not emit. That allowance is retired rather than added
   to: two offsets for one obstacle is how they drift apart.

   px throughout, because the thing being cleared is px: matching it with a rem
   value would drift the moment the root font-size changes, and mdwds.min.css does
   change it (.875rem below 30em). The band does not get taller at 48em, so there
   is no second breakpoint to keep in step any more.

   Applied to the ids the rail links to, not to [id] generally, so an unrelated
   anchor elsewhere on the page keeps the browser's own behaviour. */
#signin,
#forms,
#how,
#reports,
#who,
#help {
    scroll-margin-top: calc(var(--lp-rail-h) + 14px);
}

/* ------------------------------------------------- 6. back to the jump menu

   THE BUTTON THE INSTRUCTION ASKED FOR: "have top button to move back to this
   jump menu". It is not redundant with the sticky band, and the reason is the
   narrow breakpoint below — on a phone the rail UN-sticks (a wrapped two-line
   strip is ~115px, 18% of a 640px viewport), so this is the only way back to
   it there. On a wide screen it is the keyboard and long-page answer: the band
   is visible, but getting the CARET back to it still means scrolling.

   IT TARGETS THE RAIL, NOT THE TOP OF THE DOCUMENT. href="#pagetop" is the nav
   itself, so the reader lands on the menu rather than on the hero and has to
   scroll down past it again.

   ALWAYS VISIBLE, BECAUSE THE ALTERNATIVE NEEDS JAVASCRIPT. Revealing it after
   an arbitrary scroll distance requires a scroll listener, and this page loads
   no script for its own content on purpose. A control that is always there is
   also never a surprise.

   NOT A SOLID ACCENT FILL, AND THAT IS THE THEMING TRAP AVOIDED. The obvious
   treatment — white text on var(--c-primary-dark) — is safe in light (8.2:1) and
   BROKEN in dark: theme.css re-points --c-primary-dark to --t-accent-strong,
   which in the dark theme is a LIGHT accent intended to carry text on a dark
   surface, not to sit behind white. Paper ground with accent text and an accent
   border inverts correctly in both themes by construction, needs none of
   theme.css's internal --t-* roles, and is the same palette as the tabs, so the
   two read as one control set. */
.lp-totop {
    position: fixed;
    right: var(--sp-2);
    bottom: var(--sp-2);
    /*  One above the rail, so it is never clipped by the band it points at. */
    z-index: 6;

    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 44px;
    padding: .5rem .9rem;
    font-size: var(--fs-3xs);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-tight);
    color: var(--c-primary-dark);
    background: var(--c-paper);
    border: 1px solid var(--c-primary-dark);
    border-radius: var(--radius-pill);
    /*  Elevation is what separates it from whatever band it happens to be
        floating over — without it the button reads as part of the content. */
    box-shadow: var(--shadow-2);
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

.lp-totop:hover {
    background: var(--c-primary-lighter);
    color: var(--c-primary-darker);
    text-decoration: underline;
}

.lp-totop:focus-visible {
    box-shadow: var(--focus-ring);
    outline: none;
}

/* --------------------------------------------------- 3. "Which one is mine?"

   THE POINT OF THIS BOX IS THAT THE RULE IS WRITTEN DOWN. The application has
   always decided the sign-in route from the email address — a @maryland.gov
   address with no plus tag goes to the state account, everything else to a
   portal password — but that rule existed only in C#. A person whose sign-in
   fails cannot read C#, and "invalid credentials" does not tell them they used
   the wrong door. This box says it in English, beside the two doors.

   It is styled as a callout, not a card: sunken ground and a primary left rule,
   so it reads as guidance ABOUT the choice below rather than a third option
   competing with the two lanes. */
.lp-door {
    background: var(--c-paper-sunken);
    border: var(--border-1);
    border-left: 4px solid var(--c-primary);
    border-radius: var(--radius-md);
    padding: var(--sp-2);
    margin: 0 0 var(--sp-3);
}

.lp-door__head {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    font-size: var(--fs-2xs);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-snug);
    color: var(--c-ink);
    margin: 0 0 var(--sp-15);
}

.lp-door__head > i {
    flex: 0 0 auto;
    color: var(--c-primary);
    font-size: .95em;
}

/*  auto-fit, so the three cases sit side by side where there is room and stack
    where there is not. 15rem is the narrowest width at which
    "firstname.lastname@maryland.gov" still reads as one address. */
.lp-door__list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--sp-15);
    list-style: none;
    margin: 0;
    padding: 0;
}

/*  --lp-door is one colour decision per case, used only by the left rule. The
    default is the neutral so an item that ever loses its modifier renders
    plainly instead of borrowing the wrong meaning — the same guard .lp-item
    uses for --lp-duty. */
.lp-door__item {
    --lp-door: var(--c-ink-subtle);
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding-left: var(--sp-1);
    border-left: 3px solid var(--lp-door);
}

.lp-door__item--staff  { --lp-door: var(--c-primary); }
.lp-door__item--public { --lp-door: var(--c-form-green); }
.lp-door__item--note   { --lp-door: var(--c-ink-subtle); }

/*  THE LABEL STAYS INK, and the case colour lives only in the rule beside it.
    Tinting this text with --lp-door would put --c-form-green on a sunken ground
    at 12px, which is the one thing on this page most likely to fail 4.5:1 —
    and it would buy nothing, because each label already says which case it is
    in words. Colour is reinforcement here, never the carrier. */
.lp-door__k {
    font-size: var(--fs-4xs);
    font-weight: var(--fw-bold);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--c-ink);
}

.lp-door__v {
    font-size: var(--fs-3xs);
    line-height: var(--lh-snug);
    color: var(--c-ink-muted);
    /*  These sentences contain email addresses — unbreakable 30-character
        tokens. In a 15rem column an address that cannot break pushes the box
        wider than the viewport and the page scrolls sideways. `anywhere` lets
        the address reflow; break-all is deliberately NOT used, because it
        would also chop the ordinary prose around it. */
    overflow-wrap: anywhere;
}

.lp-door__foot {
    font-size: var(--fs-3xs);
    line-height: var(--lh-snug);
    color: var(--c-ink-subtle);
    margin: var(--sp-15) 0 0;
    padding-top: var(--sp-1);
    border-top: var(--border-1);
    max-width: var(--maxw-prose);
}

/* ------------------------------------------------------- 4. the duty legend

   The flow tags thirteen obligations Required / Conditional / Optional and
   Driller / County, and colours the left rule of each item to match. Before
   this legend the colour was undocumented: a reader could see that three items
   were amber and not learn what amber meant. The legend is placed immediately
   above the flow so it is read before the thing it explains.

   Its labels come from the SAME dutyLabel / whoseLabel dictionaries the badges
   are rendered from, so the key cannot drift from the thirteen items it
   describes. That is in the markup; this file only lays it out. */
.lp-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1) var(--sp-3);
    list-style: none;
    margin: 0 0 var(--sp-2);
    padding: var(--sp-15);
    background: var(--c-paper);
    border: var(--border-1);
    border-radius: var(--radius-md);
}

/*  --lp-duty IS RE-DECLARED HERE, AND THE VALUES MUST STAY IN STEP WITH
    home-landing.css:736-746. The rules there are scoped to .lp-item, so they
    do not reach a legend swatch; CSS has no way to share the mapping without
    editing that file, which this sheet exists not to do. If a duty colour
    changes there, change it here — the legend claiming a colour the items do
    not use is worse than no legend. */
.lp-legend__i {
    --lp-duty: var(--c-ink-subtle);
    display: flex;
    align-items: baseline;
    gap: .4rem;
    font-size: var(--fs-3xs);
    line-height: var(--lh-snug);
    color: var(--c-ink-muted);
}

.lp-legend__i[data-duty="req"]  { --lp-duty: var(--c-primary); }
.lp-legend__i[data-duty="cond"] { --lp-duty: var(--c-form-yellow); }
.lp-legend__i[data-duty="opt"]  { --lp-duty: var(--c-ink-subtle); }

/*  The swatch is the only place the duty colour is used as a fill, which is
    what makes it a legend: a reader matches this square to the rule down the
    left edge of an item. A 1px ink border keeps a pale fill visible on white
    and gives the swatch an edge to survive forced-colours as a shape.
    align-self centres it against the cap height of the label beside it. */
.lp-legend__sw {
    flex: 0 0 auto;
    align-self: center;
    width: .8rem;
    height: .8rem;
    border-radius: var(--radius-sm);
    background: var(--lp-duty);
    border: 1px solid var(--c-ink-subtle);
}

/*  THE 'WHOSE' KEY IS A SHAPE, NOT A COLOUR, because the whose tags are not
    colour-coded — they are the neutral pill (.lp-tag--whose). An outlined
    pill here says "look for a pill like this", which is true; a coloured
    square would have promised a colour distinction the flow does not make. */
.lp-legend__sw--whose {
    width: 1.5rem;
    background: transparent;
    border-radius: var(--radius-pill);
    border-color: var(--c-ink-subtle);
}

.lp-legend__k {
    font-weight: var(--fw-semibold);
    color: var(--c-ink);
    white-space: nowrap;
}

.lp-legend__v {
    color: var(--c-ink-muted);
}

/* ------------------------------------------------------------------ narrow */

/*  Matches the breakpoint home-landing.css already uses for this page, so the
    page has one small-screen story rather than two. */
@media (max-width: 40rem) {

    /*  IT STOPS STICKING ON A PHONE, AND THAT IS ARITHMETIC, NOT TASTE. Six tabs
        wrap to two lines here, which makes the band 44 + 2 + 44 + 24 + 1 = 115px.
        Pinned to the top of a 640px viewport that is 18% of the page gone on
        every scroll, and on a landscape phone nearer a third — so the menu would
        be costing more reading than it saves. It reverts to a normal band, read
        once on arrival, and .lp-totop below is what brings the reader back to it.

        static, NOT `position: sticky` with a large top: sticky with no offset
        still occupies the band and still clips. */
    .lp-rail {
        position: static;
    }

    .lp-rail__list {
        padding: var(--sp-15) var(--sp-2);
    }

    /*  ONCE IT NO LONGER STICKS, NOTHING IS COVERING THE HEADINGS, so the anchor
        offset collapses to a small courtesy gap. Leaving the 69px band allowance
        in place would strand every jumped-to heading a third of a screen down. */
    #signin,
    #forms,
    #how,
    #reports,
    #who,
    #help {
        scroll-margin-top: var(--sp-2);
    }

    /*  The tabs keep their 44px height — they are the touch targets on this
        page and are not negotiable — but the horizontal padding comes in so
        six of them fill two lines rather than three. */
    .lp-rail__link {
        padding: .5rem .7rem;
    }

    .lp-door {
        padding: var(--sp-15);
    }

    /*  The legend goes to one item per line. Wrapped mid-line, a key reads as
        "Required owed on every permit package. Conditional depends..." with no
        visible boundary between entries, which is worse than four lines. */
    .lp-legend {
        flex-direction: column;
        gap: var(--sp-1);
    }

    /*  THE SAME 12px AND 13px FLOORS home-landing.css sets for the small-label
        family and the rule text, applied to the new components for the same
        measured reason: mdwds.min.css drops the ROOT font-size to .875rem
        below 30em, so --fs-4xs (12px) lands at 10.5px and --fs-3xs (13px) at
        11.4px on a 390px phone. These are the words that tell a reader which
        sign-in is theirs; 10.5px is where they stop being read.

        px, not a larger token, because a token shrinks again with the root —
        the point is a floor that does not scale. */
    .lp-door__v,
    .lp-door__foot,
    .lp-legend__i,
    .lp-hero__official {
        font-size: 13px;
    }

    .lp-door__k,
    .lp-rail__link {
        font-size: 12px;
    }
}

/* ---------------------------------------------------------- reduced motion */

/*  The tab's colour transition is decoration; the state is carried by the
    underline itself, which still appears instantly. */
@media (prefers-reduced-motion: reduce) {

    .lp-rail__link,
    .lp-totop {
        transition: none;
    }
}

/*  SMOOTH SCROLLING IS OPT-IN AND STAYS OPT-IN. This sheet deliberately does
    NOT set `scroll-behavior: smooth` on :root, even though it would make the
    jump-and-return feel better, because on a page this tall a smooth jump to
    #help is a long animated ride that a reader with vestibular sensitivity
    cannot interrupt. The instant jump is also the one that keeps the sticky
    menu legible throughout. If it is ever added it belongs behind
    `@media (prefers-reduced-motion: no-preference)`, never unconditionally. */

/* ------------------------------------------------------------ forced colours

   In forced-colours mode the user agent replaces every author colour with one
   of its own, and DISCARDS backgrounds on small elements outright. Three things
   here would otherwise be lost rather than recoloured:

     - the hero's official line, which is white text that relied on the hero's
       discarded gradient;
     - the door's left rules and the legend's swatches, whose meaning is shape
       plus colour and which survive here as shape alone. That is acceptable
       only because both are labelled in words — the colour was never the only
       carrier — but a rule that vanishes entirely takes the grouping with it;
     - the rail's tabs, which would flatten into a row of bare words, and the
       band behind them, which MUST stay opaque: it is sticky, so a discarded
       background would let the page's own text scroll through the menu. */
@media (forced-colors: active) {

    .lp-hero__official {
        color: CanvasText;
    }

    /*  forced-colors honours `background-color` on this — it is a block-level
        band, not a small control — but state it explicitly rather than relying
        on the inherited Canvas, because the whole point of the band is that
        nothing shows through it while it is pinned. */
    .lp-rail {
        background: Canvas;
        border-bottom: 1px solid CanvasText;
    }

    /*  The 3px bottom edge is the only thing distinguishing a hovered tab from
        a resting one, and forced-colors would paint every border the same
        CanvasText — losing the distinction. Restoring it as `Highlight` on the
        interactive states keeps the affordance in a mode that has no fills. */
    .lp-rail__link {
        border-bottom-color: transparent;
        color: LinkText;
        background: Canvas;
    }

    .lp-rail__link:hover,
    .lp-rail__link:focus-visible {
        border-bottom-color: Highlight;
    }

    /*  The button is a small control, so its background IS discarded — without
        an explicit border it becomes floating text over whatever it covers. */
    .lp-totop {
        background: Canvas;
        border: 1px solid CanvasText;
        color: LinkText;
    }

    .lp-totop:hover,
    .lp-totop:focus-visible {
        border-color: Highlight;
        color: Highlight;
    }

    .lp-door {
        border-color: CanvasText;
        background: Canvas;
    }

    .lp-door__item {
        border-left-color: CanvasText;
    }

    .lp-legend {
        border-color: CanvasText;
        background: Canvas;
    }

    /*  forced-colors keeps `border` but drops `background`, so a filled swatch
        becomes an empty box. Painting it with CanvasText keeps all three duty
        swatches as one solid marker — they become indistinguishable from each
        other, which is exactly what the mode does to the item rules they refer
        to, so the legend stays TRUE. The whose swatch stays hollow and is
        still told apart by its shape. */
    .lp-legend__sw {
        background: CanvasText;
        border-color: CanvasText;
    }

    .lp-legend__sw--whose {
        background: Canvas;
        border-color: CanvasText;
    }
}

/* ------------------------------------------------------------------- print */

@media print {

    /*  A jump menu is unusable on paper — every target is on the same sheet
        and none of the links can be followed. The floating button goes with it,
        and would otherwise print once on top of the first page's content.

        `position: static` is set as well as `display: none` on purpose: it is
        the declaration that matters if anyone ever prints the rail deliberately
        (a sticky element in a paged context is repositioned unpredictably, and
        Chromium has printed one over the body text). */
    .lp-rail,
    .lp-totop {
        display: none;
        position: static;
    }

    /*  With nothing pinned there is nothing to clear, and a 69px + 14px offset
        on a printed heading is 83px of blank paper before each section. */
    #signin,
    #forms,
    #how,
    #reports,
    #who,
    #help {
        scroll-margin-top: 0;
    }

    .lp-hero__official {
        color: #000;
    }

    /*  The door and the legend DO print, and both are wanted: the door is what
        an office pins beside a shared workstation to answer "which sign-in do
        I use", and the legend is the key to a checklist printed for the field.
        They lose their fills and keep their structure. */
    .lp-door,
    .lp-legend {
        background: none;
        box-shadow: none;
        break-inside: avoid;
    }

    .lp-legend__sw {
        /*  A colour fill is not reproduced by most print settings, so the
            swatch is printed as an outline and identified by the label beside
            it — which is the same information, since the fill only ever
            pointed at a colour the paper does not have either. */
        background: none;
        border: 1px solid #000;
    }

    /*  BEST EFFORT, AND ONLY THAT. A <details> the reader collapsed before
        printing hides its own content, and CSS cannot force it open — whether
        this reveals the body depends on the engine. It is worth having because
        the failure it addresses is silent: a page that prints with three of
        its five sections missing and no sign that they were there. */
    .lp-collapse:not([open]) > .lp-collapse__body {
        display: block;
    }
}
