/* ============================================================================
   HotelTRS auth pages - the public /Account/* shell

   Loaded after components.css. Kept out of components.css deliberately: this
   is page furniture for ten pages, not a primitive, and it would double that
   file's size.

   EVERY selector descends from a trs-auth- prefixed class, on purpose. The
   markup this replaces redefined .container, .col-6, .button, .background and
   .form-control - all Bootstrap or generic names. That was survivable only
   because it lived in a <style> element on a page with nothing else on it. The
   moment those rules move to a stylesheet in <head> they hit every page in the
   application, so nothing here may be named after a Bootstrap class.

   ----------------------------------------------------------------------------
   THE CENTRED CARD

   This replaced a fixed 891x541 two-column panel floating on a flat
   var(--trs-p-600) slab. Three things were wrong with that shape and all three
   are gone:

     1. The second column was labelled "artwork" and contained the logo AGAIN,
        stretched inside a dark box - and the logo was trs_logo.png, a white
        circular VINARIJA WINERY emblem, a client's mark rather than the
        product's. It was drawn twice per page, once through filter: invert(1)
        to make a white-on-white mark visible. Both are gone; the card carries
        the HOTEL TRS wordmark that NavMenu, Register, LoadingOverlay and every
        outbound email already use.

     2. width: 891px and height: 541px were pinned, so the only responsive
        story available was one breakpoint at 1250px that hid the artwork. A
        max-width card needs no breakpoint at all above 452px.

     3. var(--trs-p-600) is a MID-RAMP step, and mid-ramp steps do not flip
        with the theme - p-600 is #4C7A66 in light and #7FB79C in dark, so the
        login page was the one screen in the application that got BRIGHTER in
        dark mode. Page grounds must be built from steps that move in the same
        direction as the theme. See the ground block below.
   ============================================================================ */

/* The page ground.

   A single 135deg diagonal: green in the top-left corner, washing out to the
   --trs-bg base by the bottom-right, plus the brand mark as an oversized
   watermark (the ::before below).

   WHERE EACH PIECE OF TEXT LANDS IS ARITHMETIC, NOT GUESSWORK. For a
   45-degree-family gradient, progress at a point is t = (x+y)/(W+H). With
   stops at 0% / 50% / 85% that puts:

     card centre     t = 0.50 exactly, on any viewport
     page footer     t = 0.68 (1920x1080) .. 0.81 (480x800)
     watermark       t = 1.00, on the bare base
     lang selector   t = 0.64 wide, but t = 0.38 on a phone - IN THE GREEN

   THE MID STOP IS AT 77%, WHICH PUTS THE FOOTER INSIDE THE GREEN RAMP. That
   is the whole reason .trs-auth-footer takes --trs-text rather than
   --trs-text-secondary. Measured at the footer's own worst position, t = 0.68,
   where the ground is #CDDBD3:

     --trs-text-secondary   4.14   FAILS - and 4.07 over the watermark
     --trs-text            ~10.2   passes with room to spare

   The footer links stay --trs-text-primary: 5.05 there, 4.96 over the
   watermark. Only the copy line had to change.

   IF YOU CHANGE THE ANGLE OR THE STOPS, RECOMPUTE t FOR THE FOOTER. On the
   green corner itself --trs-text measures 1.22 and even --trs-text-primary
   measures 1.00 - the corner is nearly the same colour as the link. The safety
   here comes entirely from the footer sitting at t > 0.68, not from the
   colours being safe everywhere.

   THE TWO THEMES USE DIFFERENT MID STOPS, and this time that is justified
   rather than lazy - the ramps are not perceptually symmetric at these
   positions. In light, --trs-p-100 is DARKER than the card, so the card gains
   separation from it: 1.22, up from 1.09. In dark, --trs-p-100 is BRIGHTER
   than the card (#1A2E25 luminance .0231 against #202422 at .0168), so using
   it would put the card in a brighter field and invert the figure-ground.
   Dark drops to --trs-p-50 for the mid, which keeps the card the brighter
   object, and only the corner itself rises above it - a corner glow, which is
   the intent.

   The first version of this got that wrong in a way worth recording, because
   measuring contrast did not catch it - it needed measuring VISIBILITY:

     - The dark base was --trs-surface-sunken (#121513), DARKER than any other
       page ground in the application, which made the page read as a black void
       rather than a dark page.
     - The two washes were mapped to different tokens per theme, and in both
       themes one of them was invisible. Dark: the cool wash measured 1.048
       against its base. Light: the warm wash (--trs-p-50) measures 5.43
       against --trs-text-secondary where the bare base measures 5.45 - the
       same colour to a reader. So a "three layer" ground was really two.

   A layer needs roughly a 1.06 ratio against what it sits on before anyone can
   see it. --trs-p-100 measures 1.13 in light and 1.22 in dark. --trs-p-200 was
   the obvious next step up in dark and is NOT usable: it drops the footer text
   over the watermark to 4.31 at every opacity, below AA.

   The two lobes share one colour, so where they overlap the result never
   exceeds --trs-p-100 - which is what keeps the worst-case ground under the
   footer predictable.

   A 32px dot grid used to be the first background layer and is gone. The mark
   is a ring of thin letterforms, and two fine textures at once turned the
   ground to mush. To bring it back, re-add a
   radial-gradient(circle at 1px 1px, ...) layer here at a 32px
   background-size. */
.trs-auth-bg {
    /* p-700 is #3A5E4F, within 17 total channel-steps of the #376548 Marko
       picked by eye - close enough to be the same colour, and it comes through
       the ramp instead of being a literal. */
    --trs-auth-corner: var(--trs-p-700);
    --trs-auth-mid:    var(--trs-p-100);

    /* The watermark. Ink and strength are separate tokens so the mark can be
       tuned without reaching for a different ramp step.

       BOTH OPACITIES ARE MEASURED CEILINGS, NOT TASTE CALLS. The page footer
       has no background of its own, so its text composites straight onto
       ground + mark, and the brightest ground layer under the mark is
       --trs-p-100 in both themes.

       Light, --trs-text-secondary over the mark: .38 gives 4.51 on the wash,
       4.85 on the base. .42 drops the wash to 4.47 and fails.

       Dark, --trs-text-primary over the mark: .45 gives 4.66 on the wash. .50
       gives 4.50 and fails - which is what the shipped value was.

       Both are set to the value that stays correct wherever the mark is
       positioned, rather than the value that happens to look fine while it is
       in the corner. Raise either only after re-running
       .design-system/scripts/contrast-audit.py. */
    --trs-auth-mark:         var(--trs-p-200);
    --trs-auth-mark-opacity: .38;
    --trs-auth-mark-size:    620px;

    /* Height of the fixed EU funding band plus breathing room. Declared here
       rather than buried in the padding shorthand so the short-viewport media
       query can zero it in one place. */
    --trs-auth-eu-reserve: 5.5rem;

    /* Containing block for .trs-auth-lang, which is absolutely positioned.
       The old ground was itself absolute and provided this by accident. */
    position: relative;

    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    min-height: 100vh;   /* fallback first - dvh is unknown to older engines */
    min-height: 100dvh;  /* mobile browser chrome */
    width: 100%;
    padding: var(--trs-space-10) var(--trs-space-4) var(--trs-auth-eu-reserve);

    background-color: var(--trs-bg);
    background-image: linear-gradient(135deg,
        var(--trs-auth-corner) 0%,
        var(--trs-auth-mid) 77%,
        var(--trs-bg) 85%);
    background-repeat: no-repeat;
}

/* The brand mark, as a MASK rather than an image.

   trs_logo.png is a pure-white mark - measured: average luma 253.0, zero
   pixels below 128 - which is why every previous use of it needed a
   filter: invert(1) to be visible on a light ground, and why it was invisible
   in dark mode until dark.css and auth.css were reconciled.

   None of that applies to a mask. mask-image reads the file ALPHA channel, not
   its colour, and the measured alpha is a real one: 74.2% fully transparent,
   16.6% opaque, 9.1% anti-aliased edge. So the mask takes the ring shape and
   background-color supplies the ink - which means the ink is a design token,
   correct in both themes, with no filter and no hex.

   A mask is also the way round the reason this ground is built from gradients
   rather than an SVG: a data-uri is a separate document and CSS custom
   properties do not cross that boundary, so an SVG used as background-image
   would have to carry a literal hex and would then be wrong in one theme. Used
   as a mask, the asset carries geometry and the token carries colour, so the
   objection does not apply.

   Absolutely positioned on purpose. .trs-auth-bg is a flex container, so a
   static ::before would become a third flex item and sit between the card and
   the footer. An absolutely positioned child is not a flex item.

   The whole rule sits inside @supports because the failure mode otherwise is
   ugly: with no mask support, background-color would paint as a solid block of
   eucalyptus over the entire ground. Unsupported browsers get no watermark at
   all, which is the correct degradation. */
@supports ((-webkit-mask-image: url("/content/trs_logo.png")) or (mask-image: url("/content/trs_logo.png"))) {
    .trs-auth-bg::before {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;

        background-color: var(--trs-auth-mark);
        opacity: var(--trs-auth-mark-opacity);

        -webkit-mask-image: url("/content/trs_logo.png");
                mask-image: url("/content/trs_logo.png");
        -webkit-mask-repeat: no-repeat;
                mask-repeat: no-repeat;
        /* Anchored past the corner so the ring crops, reading as a seal rather
           than a sticker. Kept out of the centre deliberately - a mark behind
           the form would fight the text sitting on top of it. */
        -webkit-mask-position: right -120px bottom -120px;
                mask-position: right -120px bottom -120px;
        -webkit-mask-size: var(--trs-auth-mark-size) var(--trs-auth-mark-size);
                mask-size: var(--trs-auth-mark-size) var(--trs-auth-mark-size);
    }
}

/* Dark is NOT a matter of letting the tokens flip. --trs-p-100 in dark is
   #1A2E25, relative luminance .0231, which is LIGHTER than --trs-surface in
   dark (#202422, .0168) - so reusing the light mapping would ring the card
   with a halo brighter than the card itself. Every layer steps down instead,
   so the card stays the brightest object on the page in both themes.
   Measured, not assumed.

   Written by hand as an explicit pair rather than left to dark.css: that file
   is generated, and this is the established pattern in this stylesheet - see
   the autofill block further down. */
:root[data-theme="dark"] .trs-auth-bg {
    /* p-300 in dark is #3A5E4F - the SAME HEX light reaches through p-700. So
       the corner is literally the same green in both themes, arrived at from
       opposite ends of the ramp, which is a neat property worth keeping.

       The mid drops to p-50: p-100 is brighter than the card (#1A2E25 at .0231
       against #202422 at .0168) and would invert the figure-ground. With p-50
       the card sits on #20362D and separates at 1.21 - more than the 1.09 it
       had before, with the polarity reversed (a recessed card on a lit ground,
       which is a normal dark-UI reading and the border carries it). */
    --trs-auth-corner: var(--trs-p-300);
    --trs-auth-mid:    var(--trs-p-50);

    /* p-200 is too close to the dark ground to register as a mark, so the ink
       steps up to p-300. .45 rather than .5 because .5 puts the footer link
       over the mark at exactly 4.50. */
    --trs-auth-mark:         var(--trs-p-300);
    --trs-auth-mark-opacity: .45;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .trs-auth-bg {
        /* p-300 in dark is #3A5E4F - the SAME HEX light reaches through p-700. So
           the corner is literally the same green in both themes, arrived at from
           opposite ends of the ramp, which is a neat property worth keeping.

           The mid drops to p-50: p-100 is brighter than the card (#1A2E25 at .0231
           against #202422 at .0168) and would invert the figure-ground. With p-50
           the card sits on #20362D and separates at 1.21 - more than the 1.09 it
           had before, with the polarity reversed (a recessed card on a lit ground,
           which is a normal dark-UI reading and the border carries it). */
        --trs-auth-corner: var(--trs-p-300);
        --trs-auth-mid:    var(--trs-p-50);

        /* p-200 is too close to the dark ground to register as a mark, so the ink
           steps up to p-300. .45 rather than .5 because .5 puts the footer link
           over the mark at exactly 4.50. */
        --trs-auth-mark:         var(--trs-p-300);
        --trs-auth-mark-opacity: .45;
    }
}

/* Shared with Register.razor - do not change the positioning model. */
.trs-auth-lang {
    position: absolute;
    top: var(--trs-space-5);
    right: var(--trs-space-6);
    z-index: 10;
}

/* The card. Deliberately the same instrument as .trs-card in components.css:
   --trs-surface, a 1px --trs-border, --trs-radius-lg and --trs-elevation-2, so
   it reads as the same object as every other card in the application.

   Not <TrsCard>: that wraps Blazorise Card/CardBody, which emits .card and
   .card-body and takes its colours from the theme's <style> element inside
   <body> - the sheet that beats any equal-specificity stylesheet rule on
   document order. This needs exact control of its padding and its ground, so
   it is a plain Div carrying .trs-card's recipe.

   radius-lg (16px) on the container, radius-md (11px, the signature of this
   direction) on every control inside it. That pairing is intentional. */
/* position: relative is load-bearing here, not decoration. The watermark is an
   absolutely positioned ::before, and positioned elements paint above static
   in-flow siblings; making the card positioned too puts them at the same
   level, where DOM order decides - and the ::before is first. Without this the
   mark paints over the form. The footer no longer needs its own position: it
   is inside the card. */
.trs-auth-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 420px;
    padding: var(--trs-space-8);
    background: var(--trs-surface);
    border: 1px solid var(--trs-border);
    border-radius: var(--trs-radius-lg);
    box-shadow: var(--trs-elevation-2);
}

/* The brand lockup - emblem plus wordmark - at the top of the card, with a
   hairline separating it from the form below. The row owns the bottom margin
   so neither child carries one. */
.trs-auth-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--trs-space-3);
    padding-bottom: var(--trs-space-5);
    margin-bottom: var(--trs-space-5);
    border-bottom: 1px solid var(--trs-border);
}

/* The wordmark, MASKED rather than drawn as an image - which is what lets it
   take a colour at all.

   HotelTRS-title.png measures 559x93 and is dark ink on transparency: average
   luma 11.0, max 34, every opaque pixel under 128. As an <img> it can only be
   the ink colour it was saved as, which is why dark.css carries
   `img[src*="HotelTRS-title"] { filter: invert(1) hue-rotate(180deg)
   brightness(1.6) }` to make it usable on a dark card - a crude transform that
   this page no longer depends on. Masked, the ink is --trs-text-primary and
   flips correctly on its own.

   That dark.css rule still applies to NavMenu, Register, LoadingOverlay and
   the email templates, which keep the <img>. It simply stops matching here,
   because this is a Div and not an img - so there is no double-inversion to
   worry about. */
.trs-auth-wordmark {
    width: 172px;
    max-width: 100%;
    aspect-ratio: 559 / 93;   /* => renders 28.6px tall at 172px wide */
}

/* The ring emblem beside the wordmark - trs_logo.png again, masked for the
   same reason the watermark is: the file is a pure-white mark, so as an
   <Image> it would be invisible on the light card and need a filter, but as a
   mask it takes --trs-text and is correct in both themes with no filter at
   all. --trs-text is chosen to match the wordmark, which is near-black ink in
   light and inverted to near-white by dark.css in dark.

   40px against the wordmark's 28.6px: the emblem is a circle and the wordmark
   is a cap-height word, so matching their heights exactly makes the circle
   read as smaller than it is.

   Inside @supports for the same reason as the watermark - without mask
   support, background-color would paint a solid 40px block. Here the fallback
   is no emblem, and the wordmark alone, which is exactly how the card looked
   before this was added. */
@supports ((-webkit-mask-image: url("/content/trs_logo.png")) or (mask-image: url("/content/trs_logo.png"))) {
    .trs-auth-emblem,
    .trs-auth-wordmark {
        /* --trs-text-primary, not --trs-text. The brand lockup is the one place
           on the card that should carry the brand colour, and p-700 is the SAME
           #3A5E4F the ground's top-left corner uses - so the card echoes the
           gradient. p-600 in dark. Measured on the card: 7.26 light, 6.85 dark,
           and these are large graphics where even 3:1 would do.

           The functional heading below stays --trs-text, so brand and function
           are visibly different things. */
        background-color: var(--trs-text-primary);

        -webkit-mask-repeat: no-repeat;
                mask-repeat: no-repeat;
        -webkit-mask-position: center;
                mask-position: center;
        -webkit-mask-size: contain;
                mask-size: contain;
    }

    .trs-auth-emblem {
        flex-shrink: 0;
        width: 40px;
        height: 40px;
        -webkit-mask-image: url("/content/trs_logo.png");
                mask-image: url("/content/trs_logo.png");
    }

    .trs-auth-wordmark {
        -webkit-mask-image: url("/content/login/HotelTRS-title.png");
                mask-image: url("/content/login/HotelTRS-title.png");
    }
}

/* A real h1 now - Blazorise <Heading Size="HeadingSize.Is1">. It was a
   <Label> carrying an h1's job with no `for` attribute, which was wrong twice
   over. Margins are set explicitly because Bootstrap gives h1 its own. */
.trs-auth-heading {
    /* The bottom margin is for whatever follows the heading DIRECTLY - an
       alert on the four terminal pages, a field on the delete-request page.
       The subtitle overrides it below. */
    margin: 0 0 var(--trs-space-4);
    /* Deliberately quiet: 18px at weight 500, not 28px bold.

       It was 2xl/bold for one iteration and Marko's read was right - "too big
       and not in style of whole login page". A heavy sans heading is a
       different register from an elegant serif wordmark sitting right above
       it, and at 28px it was competing with the brand rather than labelling
       the form. 18px/500 gives it enough weight against the 14px subtitle to
       be a heading, and no more.

       Neutral, not green. The brand lockup is the one element carrying the
       brand colour; a second green element would leave the card with no
       neutral anchor. */
    font-size: var(--trs-text-lg);
    font-weight: var(--trs-weight-medium);
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: var(--trs-text);
}

.trs-auth-subtitle {
    margin: 0 0 var(--trs-space-6);
    font-size: var(--trs-text-base);
    line-height: 1.45;
    color: var(--trs-text-secondary);
}

/* A heading and its subtitle read as one unit, so they sit 4px apart rather
   than the 16px the heading reserves for content that follows it directly.
   A negative margin rather than .trs-auth-heading:not(:has(+ ...)), so the
   spacing cannot silently depend on selector support - if :has() were missing
   there, every heading would lose its margin instead of just this pair. */
.trs-auth-heading + .trs-auth-subtitle {
    margin-top: calc(-1 * var(--trs-space-3));
}

/* Replaces an inline style repeated on ten alert elements:
   font-size: 0.8125rem; padding: 0.5rem 0.75rem; border-radius: 0.5625rem.
   Left-aligned now - centred body copy inside a 356px column reads as a
   banner rather than as a message about the field above it. */
.trs-auth-alert {
    font-size: var(--trs-text-sm);
    padding: var(--trs-space-3);
    border-radius: var(--trs-radius-md);
    margin-bottom: var(--trs-space-4);
}

/* Inside the card now, under a hairline mirroring the one above the brand
   lockup. It has moved twice, and both moves were forced by contrast:

   1. Originally position: absolute against the viewport, coloured
      --trs-on-primary for the old eucalyptus slab. On the gradient ground that
      pair measures 1.04:1 - invisible.
   2. Then in the page flow below the card, which put it at t = 0.68..0.81 of
      the 135deg gradient - INSIDE the green ramp, where --trs-text-secondary
      measures 4.14 and fails AA. It had to be forced to the near-black
      --trs-text, far too loud for a footer.

   On --trs-surface the quiet grey measures 5.95 / 6.86 and is correct again.

   The wider win: the gradient now carries no text at all. The stops, the angle
   and --trs-auth-mark-opacity are no longer pinned by anything - see the notes
   on .trs-auth-bg, which record ceilings that no longer bind. */
.trs-auth-footer {
    margin-top: var(--trs-space-5);
    padding-top: var(--trs-space-5);
    border-top: 1px solid var(--trs-border);
    text-align: center;
    color: var(--trs-text-secondary);
    font-size: var(--trs-text-xs);
}

/* KEEP THE NEXT THREE RULES AS THEY ARE. Register.razor uses
   .trs-auth-footer-links over its own --trs-p-600 slab, where
   --trs-on-primary measures 4.65:1 and --trs-text-primary would measure
   1.48:1. Recolouring these unscoped would break a page this rework does not
   own. */
.trs-auth-footer-links {
    margin-top: var(--trs-space-2);
    display: flex;
    justify-content: center;
    gap: var(--trs-space-2);
}

.trs-auth-footer-links a {
    color: var(--trs-on-primary);
    text-decoration: underline;
}

.trs-auth-footer-links a:hover {
    text-decoration: none;
}

/* The shell's own ground gets the readable pair. (0,2,1) beats the (0,2,0)
   base rule above without touching Register. */
.trs-auth-bg .trs-auth-footer-links a {
    color: var(--trs-text-primary);
}

.trs-auth-bg .trs-auth-footer-links a:hover {
    color: var(--trs-p-800);
}

/* Secondary links under the submit button - "back to login", "create an
   account". Sixteen of these across nine auth pages carried an inline
   color: #00ADDC, the old cyan brand, which measures 2.62:1 on the white
   panel. --trs-text-primary is 7.26:1.

   Owns its own top margin, so the markup no longer carries mt-3. */
.trs-auth-link {
    display: block;
    width: 100%;
    margin-top: var(--trs-space-5);
    font-size: var(--trs-text-sm);
    color: var(--trs-text-primary);
    text-align: center;
}

.trs-auth-link:hover {
    color: var(--trs-p-800);
}


/* ----------------------------------------------------------------------------
   FORM PAGES

   The five pages with actual input fields - login, register, reset password,
   delete-account request and confirm - carried these on top of the shell CSS
   above. Same rule applies: nothing here may be named after a Bootstrap class.
   The originals redefined .form-control and .button globally.
   ---------------------------------------------------------------------------- */

.trs-auth-field {
    display: flex;
    flex-direction: column;
    gap: var(--trs-space-2);
    margin-bottom: var(--trs-space-4);
}

.trs-auth-label {
    margin: 0;
    font-size: var(--trs-text-sm);
    font-weight: var(--trs-weight-medium);
    line-height: 1.2;
    color: var(--trs-text);
}

/* Anchors the reveal button, nothing else. The decorative leading glyph it
   used to position is gone - see the note on the field below. */
.trs-auth-input {
    position: relative;
    display: flex;
    align-items: center;
}

/* One rule owns the whole field box.

   The two PNG sprites that used to sit inside these fields
   (login-email-ico.png, login-password-ico.png) are gone, along with the
   absolutely-positioned `i` that carried them and the padding-left: 2.9rem
   magic number that made room for it. They were explicitly decorative -
   pointer-events: none - and a field whose visible label already reads
   "Email" gains nothing from an envelope. On a 420px card, a decorative glyph
   on the left and a functional eye toggle on the right in the same field also
   blurred which one was clickable.

   The `> input` descendant is deliberate: the element is an <InputText>
   rendering class="form-control", so this lands at (0,2,1) against
   Bootstrap's (0,1,0) and wins without !important.

   min-height honours --trs-control-h rather than hardcoding a height, so a
   compact-density user gets 30px here. That still clears WCAG 2.2 SC 2.5.8
   (24x24 CSS px). */
.trs-auth-input > input {
    width: 100%;
    min-height: var(--trs-control-h);
    padding: var(--trs-space-2) var(--trs-space-3);
    font-size: var(--trs-text-base);
    font-weight: var(--trs-weight-regular);
    color: var(--trs-text);
    background: var(--trs-surface);
    border: 1px solid var(--trs-border-strong);
    border-radius: var(--trs-radius-md);
    transition: border-color var(--trs-motion-fast) var(--trs-ease);
}

.trs-auth-input > input:hover {
    border-color: var(--trs-text-muted);
}

.trs-auth-input > input::placeholder {
    color: var(--trs-text-muted);
    opacity: 1;
}

/* Clear the reveal button. Both selectors, because the toggle flips the type
   attribute to "text" and the first one then stops matching. */
.trs-auth-input > input[type="password"],
.trs-auth-input:has(.trs-auth-reveal) > input {
    padding-right: var(--trs-space-10);
}

/* was style="font-size:0.75rem" repeated on every ValidationMessage */
.trs-auth-validation {
    font-size: var(--trs-text-xs);
    padding: var(--trs-space-1);
}

/* Autofill. Chromium's autofill painter draws its own background over the
   field, ignores background-color, and DROPS any -webkit-box-shadow whose
   value contains a var() - so the inset shadow has to be a literal. Dark gets
   its own pair for the same reason.

   These four hexes must be kept in step with --trs-surface and --trs-text by
   hand. The previous pair had already drifted: #1E2224 / #23282B against the
   real #202422 / #26292A.

   The prefers-color-scheme twin is new. The old block covered only the
   explicit data-theme="dark" case, so a dark-OS user who had never chosen a
   theme got the light autofill pair - near-white on white inside a dark
   card. */
.trs-auth-input > input:-webkit-autofill,
.trs-auth-input > input:-webkit-autofill:hover,
.trs-auth-input > input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px #FFFFFF inset;   /* = --trs-surface light */
    -webkit-text-fill-color: #26292A;                 /* = --trs-text    light */
    caret-color: #26292A;
}

:root[data-theme="dark"] .trs-auth-input > input:-webkit-autofill,
:root[data-theme="dark"] .trs-auth-input > input:-webkit-autofill:hover,
:root[data-theme="dark"] .trs-auth-input > input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px #202422 inset;   /* = --trs-surface dark */
    -webkit-text-fill-color: #EDEFEC;                 /* = --trs-text    dark */
    caret-color: #EDEFEC;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .trs-auth-input > input:-webkit-autofill,
    :root:not([data-theme="light"]) .trs-auth-input > input:-webkit-autofill:hover,
    :root:not([data-theme="light"]) .trs-auth-input > input:-webkit-autofill:focus {
        -webkit-box-shadow: 0 0 0 1000px #202422 inset;
        -webkit-text-fill-color: #EDEFEC;
        caret-color: #EDEFEC;
    }
}

/* The explanatory block on the delete-account pages - what happens, what is
   removed, what is retained. Legally load-bearing text, so it gets real body
   contrast rather than the muted grey the originals used (#4a5568 on white). */
.trs-auth-info {
    margin: 0 0 var(--trs-space-4);
}

.trs-auth-info-heading {
    font-size: var(--trs-text-sm);
    font-weight: var(--trs-weight-medium);
    color: var(--trs-text);
    margin: var(--trs-space-3) 0 var(--trs-space-1);
}

.trs-auth-info-list {
    margin: 0 0 var(--trs-space-2) var(--trs-space-5);
    padding: 0;
    font-size: var(--trs-text-sm);
    color: var(--trs-text-secondary);
}

.trs-auth-info-text {
    font-size: var(--trs-text-sm);
    color: var(--trs-text-secondary);
    line-height: 1.5;
    margin: 0 0 var(--trs-space-3);
}

/* was .button

   display: flex rather than the old line-height: 2.625rem, because this class
   lands on an <a> on four pages and a <button> on five, and flex centres both
   without arithmetic. Dropping that line-height is also what lets
   InvalidPasswordReset drop its inline style.

   The gap leaves room for the spinner that scripts.js injects ahead of the
   label on submit - see [data-loading-btn] there.

   No transform: scale() on hover. A full-width button that grows is the dated
   tell, and it was the only reason the reduced-motion block below had
   anything to cancel. */
.trs-auth-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--trs-space-2);
    width: 100%;
    min-height: var(--trs-control-h);
    padding: var(--trs-space-2) var(--trs-space-4);
    border: none;
    border-radius: var(--trs-radius-md);
    background: var(--trs-fill);
    color: var(--trs-on-primary);
    font-size: var(--trs-text-base);
    font-weight: var(--trs-weight-medium);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    outline-offset: 2px;
    box-shadow: var(--trs-elevation-1);
    transition: background-color var(--trs-motion-base) var(--trs-ease),
                box-shadow var(--trs-motion-base) var(--trs-ease);
}

.trs-auth-btn:hover,
.trs-auth-btn:focus-visible {
    background: var(--trs-fill-hover);
    color: var(--trs-on-primary);
    box-shadow: var(--trs-elevation-2);
}

.trs-auth-btn:active {
    color: var(--trs-on-primary);
}

.trs-auth-btn:disabled {
    opacity: .7;
    cursor: default;
}

/* Stacked actions - InvalidPasswordReset offers two buttons, then a link.
   Replaces its inline margin-bottom. */
.trs-auth-btn + .trs-auth-btn {
    margin-top: var(--trs-space-3);
}

/* Irreversible action. Kept visually distinct from the primary submit so the
   delete button never reads as the ordinary "continue" on the page. */
.trs-auth-btn-danger,
.trs-auth-btn-danger:hover,
.trs-auth-btn-danger:focus-visible,
.trs-auth-btn-danger:active {
    background: var(--trs-danger);
    color: var(--trs-on-primary);
}

/* ----------------------------------------------------------------------------
   LOGIN

   The remember-me / forgot-password row and the reveal-password toggle.

   The spinner that used to live here is gone. Login.razor carried an inline
   <script> that hid every child of .trs-auth-col, measured the parent's
   offsetHeight, rewrote the column's cssText and injected a hand-built
   .trs-auth-spinner. Both of those class names were contractual for exactly
   that reason. The script is deleted, and the app's existing SSR mechanism -
   [data-loading-btn] in wwwroot/JavaScript/scripts.js, which Login's own
   forgot-password branch was already using - replaces it. So the contract is
   retired rather than re-pointed, and .trs-auth-col, .trs-auth-spinner and
   @keyframes trs-auth-spin are all gone with it.
   ---------------------------------------------------------------------------- */

/* Replaces a d-flex wrapper holding two Bootstrap .col-6 halves. */
.trs-auth-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--trs-space-3);
    margin-bottom: var(--trs-space-5);
}

.trs-auth-remember {
    display: flex;
    align-items: center;
    gap: var(--trs-space-2);
    margin: 0;
    font-size: var(--trs-text-sm);
    color: var(--trs-text-secondary);
    cursor: pointer;
}

/* The remember-me checkbox. Three inherited defects, all three visible on a
   screenshot of the running page and none of them this page's own doing:

   1. THE BORDER WAS INVISIBLE. It came from Bootstrap's --bs-border-color,
      which the token bridge maps to --trs-border (#E3E3DD): 1.29 against the
      white card. A checkbox's border IS the control, and WCAG 1.4.11 asks 3:1
      for exactly that, so this was an affordance you could not see.
      --trs-text-muted is the lightest ALIAS clearing it in both themes -
      5.52 light, 4.98 dark. n-500 measures 3.71/3.99 and sits closer to the
      threshold, but primitives are not for components to reference.

   2. IT RENDERED AS A CIRCLE. app.css has a shape exception for this - "the
      11px input radius from the Blazorise theme swallows a 16px checkbox" -
      but it is scoped `.form-check:not(.form-switch) .form-check-input`, and
      this markup is an InputCheckbox inside the <Label>, with no .form-check
      wrapper. So it missed the exception and took the theme's 11px radius on a
      ~14px box. Hence the explicit --trs-radius-sm.

   3. DARK HAD THE SAME BORDER PROBLEM. dark.css sets --trs-border-strong
      (#3F4642), which measures 1.62 against the dark card. That file is
      GENERATED and linked last, so its (0,2,1) rule cannot be edited and has
      to be out-specified - which is what the :root-prefixed pair below does at
      (0,3,1).

   Deliberately heavier than the text inputs, which sit at --trs-border-strong
   (1.63). Those are the ones that are wrong: they need a --trs-border-control
   token that does not exist yet. A 14px box that is nothing but its border and
   a 38px field with a label above it are not the same problem. */
.trs-auth-remember .form-check-input {
    /* position: static is the fix for a FOURTH defect, and the nastiest one.
       Bootstrap 4.6.1 is loaded alongside 5.3.2 (both from jsDelivr, plus a
       local copy - three Bootstraps in the page) and BS4 says:

           .form-check-input { position: absolute; margin-left: -1.25rem; }

       BS5 never declares `position` on that class, so there is nothing to
       override it and BS4's absolute survives. An absolutely positioned child
       is not a flex item: it leaves the flow, `gap` stops applying to it, and
       it paints at the label's content origin - directly on top of the "R" of
       "Remember me". BS4 got away with it because its .form-check wrapper
       supplies a matching padding-left: 1.25rem, and this markup has no
       wrapper.

       Measured in the running page: label width 88.03px, text width 88.03px -
       the checkbox contributed exactly nothing to layout. */
    position: static;
    flex-shrink: 0;
    /* 1.25em of the label's 13px = 16.25px. Not cosmetic: --trs-radius-sm is
       6px and the design system assigns it to checkboxes, but 6px on the 14.3px
       box this started at is 42% of the width, which renders as a circle and
       reads as a RADIO BUTTON. At 16.25px it is 37% and reads as a rounded
       square. The larger box is a better pointer target too. */
    width: 1.25em;
    height: 1.25em;
    margin: 0;
    border: 1px solid var(--trs-text-muted);
    border-radius: var(--trs-radius-sm);
    cursor: pointer;
}

.trs-auth-remember .form-check-input:checked {
    background-color: var(--trs-fill);
    border-color: var(--trs-fill);
}

:root[data-theme="dark"] .trs-auth-remember .form-check-input {
    border-color: var(--trs-text-muted);
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .trs-auth-remember .form-check-input {
        border-color: var(--trs-text-muted);
    }
}

/* Was #00ADDC - 2.62:1 on the white panel, and this is the escape hatch for a
   locked-out user, so it is the last link that should be hard to see. */
.trs-auth-forgot {
    font-size: var(--trs-text-sm);
    font-weight: var(--trs-weight-medium);
    color: var(--trs-text-primary);
    text-decoration: none;
    white-space: nowrap;
}

.trs-auth-forgot:hover {
    color: var(--trs-p-800);
    text-decoration: underline;
}

/* Vertically centred against whatever --trs-control-h currently is, rather
   than the old fixed top: 9px. min-width/height hold the hit area at 24px
   even though the glyph is 14px. */
.trs-auth-reveal {
    position: absolute;
    right: var(--trs-space-2);
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
    padding: 0;
    border: none;
    background: none;
    box-shadow: none;
    color: var(--trs-text-muted);
}

.trs-auth-reveal:hover,
.trs-auth-reveal:active {
    background: none;
    border: none;
    box-shadow: none;
    color: var(--trs-text);
}

/* ----------------------------------------------------------------------------
   RESPONSIVE

   The old story was a single @media (max-width: 1250px) whose entire purpose
   was display: none on the artwork column. With the card, max-width: 420px
   handles every viewport from 452px upward with no breakpoint at all.
   ---------------------------------------------------------------------------- */

/* Narrow phones. Deliberately NOT full-bleed: a 16px-radius card inside 16px
   of page padding reads better than an edge-to-edge panel, and it keeps the
   ground visible as context. */
@media (max-width: 480px) {
    .trs-auth-bg {
        padding: var(--trs-space-6) var(--trs-space-4) var(--trs-auth-eu-reserve);
    }

    .trs-auth-card {
        padding: var(--trs-space-6);
    }

    .trs-auth-footer-links {
        flex-wrap: wrap;
    }

    .trs-auth-row {
        flex-wrap: wrap;
        gap: var(--trs-space-2);
    }
}

@media (prefers-reduced-motion: reduce) {
    .trs-auth-btn,
    .trs-auth-btn:hover,
    .trs-auth-input > input {
        transition: none;
    }
}

/* ----------------------------------------------------------------------------
   REGISTER

   Register is not the two-column panel - it is a single scrolling card with a
   fixed header and a sticky footer, so it does not use TrsAuthShell. What it
   does share is the ground and the page footer, and what it used to share was
   a set of Bootstrap names (.background, .form-control, .button, .footer-links)
   redefined inside its own <style>. Those are the reason this section exists.
   ---------------------------------------------------------------------------- */

.trs-reg-bg {
    display: flex;
    position: fixed;
    width: 100%;
    height: 100%;
    background: var(--trs-p-600);
    margin: 0;
    padding: 0;
    left: 0;
    top: 0;
    align-items: center;
    flex-direction: column;
    justify-content: center;
}

.trs-reg-card {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 8rem);
    min-height: 400px;
    width: 500px;
    border-radius: var(--trs-radius-lg);
    background-color: var(--trs-surface);
    box-shadow: var(--trs-elevation-2);
    overflow: hidden;
}

.trs-reg-card-screen-selection {
    display: flex;
    flex-flow: column;
    justify-content: space-between;
    align-items: center;
}

.trs-reg-header {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--trs-space-2);
    padding: 1.75rem 2rem var(--trs-space-4);
    border-bottom: 1px solid var(--trs-border);
}

.trs-reg-title-img {
    width: 48%;
}

.trs-reg-hotel-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--trs-fill);
    color: var(--trs-on-primary);
    font-weight: var(--trs-weight-medium);
    font-size: var(--trs-text-sm);
    padding: 0.35rem var(--trs-space-4);
    border-radius: 2rem;
    margin-top: var(--trs-space-1);
}

.trs-reg-form {
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: hidden;
    min-height: 0;
}

.trs-reg-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--trs-space-5) var(--trs-space-6) var(--trs-space-2);
}

.trs-reg-section {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--trs-text-primary);
    font-weight: var(--trs-weight-medium);
    font-size: var(--trs-text-sm);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--trs-space-4);
    padding-bottom: 0.4rem;
    border-bottom: 2px solid var(--trs-p-100);
}

.trs-reg-footer {
    flex-shrink: 0;
    display: flex;
    gap: var(--trs-space-3);
    padding: var(--trs-space-4) var(--trs-space-6);
    border-top: 1px solid var(--trs-border);
    background: var(--trs-surface);
}

.trs-reg-btn {
    flex: 1;
    height: 44px;
    border: none;
    border-radius: var(--trs-radius-md);
    color: var(--trs-on-primary);
    font-size: var(--trs-text-sm);
    font-weight: var(--trs-weight-medium);
    cursor: pointer;
    box-shadow: var(--trs-elevation-1);
    transition: opacity var(--trs-motion-base) var(--trs-ease),
                transform var(--trs-motion-fast) var(--trs-ease),
                box-shadow var(--trs-motion-base) var(--trs-ease);
}

.trs-reg-btn:hover {
    opacity: 0.9;
    transform: translateY(-1px);
    box-shadow: var(--trs-elevation-2);
    color: var(--trs-on-primary);
}

@media (prefers-reduced-motion: reduce) {
    .trs-reg-btn,
    .trs-reg-btn:hover {
        transition: none;
        transform: none;
    }
}

.trs-reg-btn-back,
.trs-reg-btn-back:hover {
    background: var(--trs-danger);
}

.trs-reg-btn-submit,
.trs-reg-btn-submit:hover {
    background: var(--trs-fill);
}

/* Register's footer sits in the page flow under the card, not pinned to the
   viewport like the panel pages' - the card is already vertically centred. */
.trs-reg-page-footer {
    flex-shrink: 0;
    margin-top: var(--trs-space-5);
    text-align: center;
    color: var(--trs-on-primary);
    font-size: var(--trs-text-base);
}

/* Blazorise renders the date picker into a wrapper with display: contents,
   which nullifies position: relative and left the calendar resolving against
   .trs-reg-bg at top: 2002px. Block restores the containing box. */
.trs-reg-body .flatpickr-wrapper {
    display: block;
    width: 100%;
}

.trs-reg-body .flatpickr-calendar {
    z-index: 9999;
}

.trs-reg-body .blazorise-datetime-holder {
    width: 100%;
    border: none;
    text-align: left;
}
/* ----------------------------------------------------------------------------
   EU FUNDING DISCLOSURE

   Rendered by PublicAccountLayout as a SIBLING of @Body, so it floats over
   whatever ground the page underneath happens to paint. Four different grounds
   use that layout today:

     .trs-auth-bg   the new auth ground        (this file, above)
     .trs-reg-bg    Register's --trs-p-600 slab
     (none)         ConfirmGuest, EnterRealEmail, ConfirmGuestEmailChange -
                    bare --trs-bg, no ground class at all

   It used to be white text with a text-shadow, tuned for the eucalyptus slab.
   That measured 4.65:1 on Register and 1.04:1 on the three guest pages - which
   means a legally required funding disclosure has been rendering as a blank
   strip in production on those three. Against the new auth ground it would
   have measured 1.04:1 as well.

   So it paints its own band. An opaque --trs-bg ground with a --trs-border top
   rule and --trs-text-secondary copy is legible over all four cases with one
   rule and no scoping selector, and it cannot silently break the next time a
   ground changes. The text-shadow existed only to lift white text off a
   variable slab and is gone.
   ---------------------------------------------------------------------------- */

.eu-funding-disclosure {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--trs-space-3);
    padding: var(--trs-space-3) var(--trs-space-4);
    background: var(--trs-bg);
    border-top: 1px solid var(--trs-border);
    /* Decoration over a form - it must never intercept a click meant for a
       control behind it. */
    pointer-events: none;
}

.eu-funding-disclosure img {
    height: 30px;
    flex-shrink: 0;
}

.eu-funding-disclosure span {
    max-width: 760px;
    text-align: center;
    font-size: var(--trs-text-2xs);
    line-height: 1.35;
    color: var(--trs-text-secondary);
}

/* Short viewport. The old rule here was display: none, which hid a legally
   mandated funding statement AND the EU emblem to save 60px of height - and
   both are required by the NPOO / NextGenerationEU visual-identity rules, so
   hiding is not an available answer. The band shrinks instead. It can afford
   to stay: the copyright footer it used to collide with is now in the document
   flow inside .trs-auth-bg, above the reserved padding, so the two no longer
   compete for the same pixels. */
@media (max-height: 640px) {
    .eu-funding-disclosure {
        padding: var(--trs-space-2) var(--trs-space-4);
    }

    .eu-funding-disclosure img {
        height: 22px;
    }

    .trs-auth-bg {
        --trs-auth-eu-reserve: 4.5rem;
    }
}

@media (max-width: 480px) {
    .eu-funding-disclosure {
        flex-direction: column;
        gap: var(--trs-space-2);
    }
}
