/* Auth - the sign-in screens.

   Taken from template/tenant_template/modules/auth/css/auth.css, which is
   the design the owner chose for the SUPER panel (1 Sep 2026). The
   super_template copy was tried and rejected on the same day - it is not
   this product.

   One rename and no other change to the template's own rules: the body
   scope was `.tenant-page`, which would have put the word "tenant" on the
   control panel; it is `.signin-page` here. The owner's later changes are
   a single block at the END of this file, so the diff against the
   template stays in one place.

   The screen is a universe: five rings of what the platform runs, turning
   round the card in the middle.

   NOTHING ELSE FROM THE TEMPLATE WAS COPIED. Bootstrap, the Tabler icons,
   style.css, jQuery, the bootstrap bundle and script.js are all already in
   `Core/Ui` and are loaded from there - including the password eye, which
   is `.toggle-password` in ui/js/script.js. The only two files this screen
   adds to the platform are this one and auth.js.

   The radii, the buttons and the badges are the theme's. */

:root {
    --auth-ink: #07090a;
    --auth-ink-2: #141b1c;
    --auth-line: rgba(255, 255, 255, .10);
    --auth-dim: rgba(255, 255, 255, .64);
    --auth-faint: rgba(255, 255, 255, .44);
}

/* ---------- the form card ---------- */

/* Boxed, shadowed, and given room to breathe. The height of every
   control comes from padding on the theme's own classes, deliberately
   not from .form-control-lg or .btn-lg - each of those brings a larger
   corner radius with it and would put this page out of step with the
   rest of the product. */

.auth-right-mid {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
}

.auth-form-card {
    width: 100%;
    max-width: 470px;
    padding: 36px 38px 34px;
    box-shadow: 0 16px 40px rgba(10, 12, 12, .12);
}

.auth-head {
    margin: 0 0 6px;
    font-size: 27px;
    font-weight: 600;
    letter-spacing: -.015em;
}

.auth-sub {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.65;
    color: var(--bs-secondary-color);
}

/* the top line of the card: who this is, and the way out if it is going
   wrong. The way out belongs here rather than at the bottom, because
   somebody who cannot get in stops reading after the first screenful. */
.auth-card-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 22px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--bs-border-color);
}

.auth-mark {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 13px;
    font-weight: 600;
    color: var(--bs-body-color);
}

.auth-mark-badge {
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 5px;
    background: var(--primary);
    color: #fff;
    font-size: 16px;
}

.auth-form-card .form-label {
    font-size: 13px;
    font-weight: 500;
    margin-bottom: 6px;
    color: var(--bs-body-color);
}

.auth-form-card .form-control,
.auth-form-card .input-group-text {
    padding-top: 10px;
    padding-bottom: 10px;
}

.auth-form-card .btn {
    padding-top: 11px;
    padding-bottom: 11px;
}

.auth-terms { font-size: 12px; line-height: 1.6; }

/* the way to an account is a footer, not another line under the button.
   A rule and real space above it stop the bottom of the card reading as
   four things stacked without air. */
.auth-new {
    margin: 22px 0 0;
    padding-top: 20px;
    border-top: 1px solid var(--bs-border-color);
}

.auth-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 6px 16px;
    padding-top: 16px;
    font-size: 12px;
    color: var(--bs-secondary-color);
}

.auth-foot a { color: var(--bs-secondary-color); }

.auth-foot a:hover { color: var(--primary); }

/* ==========================================================
   Tenant login - the same card, on a universe
   ==========================================================

   A tenant does not sign in to a product, they sign in to the middle of
   everything they already use. So the page is one orbit centred on the
   card: three rings of the systems a workspace connects, turning slowly,
   with one of them lighting at a time and naming itself.

   The card is .auth-form-card, the same rule the main login uses.
   Nothing about it is restated here - if it changes there it changes
   here, which is the whole point of one stylesheet. */

.signin-page {
    min-height: 100vh;
    background:
        radial-gradient(48% 44% at 50% 46%, #ffffff 0%, rgba(255, 255, 255, 0) 68%),
        radial-gradient(70% 62% at 50% 50%, rgba(var(--primary-rgb), .12) 0%, transparent 66%),
        radial-gradient(60% 50% at 92% 96%, rgba(255, 162, 1, .16) 0%, transparent 62%),
        linear-gradient(178deg, #fbeeec 0%, #f4f6f8 52%, #fdf5ea 100%);
}

.tn-shell {
    position: relative;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 30px;
    padding: 42px 28px 38px;
    overflow: hidden;
}

/* ---------- the universe behind everything ---------- */

.tn-uni {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0;
    height: 0;
    z-index: 0;
    pointer-events: none;
}

/* the rings turn; the icons on them do not, because an upright icon is
   the only kind anybody can read */
.tn-ring {
    position: absolute;
    top: 50%;
    left: 50%;
    border: 1px dashed rgba(var(--primary-rgb), .20);
    border-radius: 50%;
    transform: translate(-50%, -50%);
}

.tn-ring-1 { width: min(96vmin, 42vw);  height: min(96vmin, 42vw);  animation: tn-spin 46s linear infinite; }
.tn-ring-2 { width: min(124vmin, 54vw); height: min(124vmin, 54vw); animation: tn-spin-back 60s linear infinite; }
.tn-ring-3 { width: min(152vmin, 66vw); height: min(152vmin, 66vw); animation: tn-spin 74s linear infinite; }
.tn-ring-4 { width: min(180vmin, 78vw); height: min(180vmin, 78vw); animation: tn-spin-back 88s linear infinite; }
.tn-ring-5 { width: min(208vmin, 90vw); height: min(208vmin, 90vw); animation: tn-spin 104s linear infinite; }

/* the further out, the fainter - which is what makes five circles read
   as depth rather than as five circles */
.tn-ring-3 { border-color: rgba(var(--primary-rgb), .16); }
.tn-ring-4 { border-color: rgba(var(--primary-rgb), .13); }
.tn-ring-5 { border-color: rgba(var(--primary-rgb), .10); }

@keyframes tn-spin {
    from { transform: translate(-50%, -50%) rotate(0deg); }
    to   { transform: translate(-50%, -50%) rotate(360deg); }
}

@keyframes tn-spin-back {
    from { transform: translate(-50%, -50%) rotate(0deg); }
    to   { transform: translate(-50%, -50%) rotate(-360deg); }
}

/* a light running each ring, so the rings read as live rather than drawn */
.tn-arm {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.tn-arm-1 { width: min(96vmin, 42vw);  height: min(96vmin, 42vw);  animation: tn-spin 11s linear infinite; }
.tn-arm-2 { width: min(124vmin, 54vw); height: min(124vmin, 54vw); animation: tn-spin-back 15s linear infinite; }
.tn-arm-3 { width: min(152vmin, 66vw); height: min(152vmin, 66vw); animation: tn-spin 19s linear infinite; }
.tn-arm-4 { width: min(180vmin, 78vw); height: min(180vmin, 78vw); animation: tn-spin-back 24s linear infinite; }
.tn-arm-5 { width: min(208vmin, 90vw); height: min(208vmin, 90vw); animation: tn-spin 30s linear infinite; }

.tn-arm::before {
    content: "";
    position: absolute;
    top: -4px;
    left: 50%;
    width: 8px;
    height: 8px;
    margin-left: -4px;
    border-radius: 50%;
    background: var(--primary);
    box-shadow:
        0 0 0 5px rgba(var(--primary-rgb), .12),
        0 0 14px 3px rgba(var(--primary-rgb), .45);
}

/* every system a workspace already runs, sitting where it sits */
.tn-orb {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 54px;
    height: 54px;
    margin: -27px 0 0 -27px;
    transform: rotate(var(--a)) translateY(calc(var(--r) * -1)) rotate(calc(var(--a) * -1));
}

.tn-orb span {
    width: 100%;
    height: 100%;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1px solid rgba(10, 12, 12, .05);
    background: #fff;
    box-shadow: 0 6px 18px rgba(10, 12, 12, .10);
    font-size: 25px;
    transition: transform .45s ease, box-shadow .45s ease;
    animation: tn-float 6s ease-in-out infinite;
}

.tn-orb.is-on span {
    transform: scale(1.16);
    box-shadow:
        0 0 0 6px rgba(var(--primary-rgb), .10),
        0 12px 26px rgba(10, 12, 12, .18);
}

@keyframes tn-float {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -5px; }
}

.tn-layer {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: rotate(var(--a)) translateY(calc(var(--r) * -1)) rotate(calc(var(--a) * -1));
}

.tn-layer span {
    display: block;
    transform: translate(-50%, -50%);
    padding: 4px 11px;
    border: 1px solid rgba(var(--primary-rgb), .28);
    border-radius: 5px;
    background: rgba(255, 255, 255, .86);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    color: var(--primary);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* the name shows only for the one that is lit, so twenty labels never
   fight each other over the same background */
.tn-orb b {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 6px;
    padding: 2px 7px;
    border-radius: 5px;
    background: var(--dark);
    color: #fff;
    font-size: 10px;
    font-weight: 500;
    letter-spacing: .04em;
    white-space: nowrap;
    opacity: 0;
    transition: opacity .35s ease;
}

.tn-orb.is-on b { opacity: 1; }

/* ---------- what is said above and below ---------- */

.tn-top,
.tn-foot {
    position: relative;
    z-index: 3;
    flex: 0 0 auto;
    text-align: center;
    max-width: 640px;
}

.tn-top .tn-logo { height: 30px; width: auto; margin-bottom: 20px; }

.tn-head {
    margin: 0 0 10px;
    font-size: 34px;
    line-height: 1.18;
    font-weight: 600;
    letter-spacing: -.02em;
}

.tn-head span { color: var(--primary); }

.tn-said {
    margin: 0 auto;
    max-width: 520px;
    font-size: 14px;
    line-height: 1.7;
    color: var(--bs-secondary-color);
}

.tn-foot p {
    margin: 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--bs-secondary-color);
}

.tn-foot b { color: var(--bs-body-color); font-weight: 600; }

/* ---------- the card in the middle of it ---------- */

.tn-mid {
    position: relative;
    z-index: 4;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

/* ---------- fitting the window ---------- */

@media (min-width: 992px) {
    html, body.signin-page { height: 100%; overflow: hidden; }

    .tn-shell { height: 100vh; min-height: 0; }
}

@media (min-width: 992px) and (max-height: 880px) {
    .tn-shell { padding: 32px 24px 28px; gap: 22px; }
    .tn-top .tn-logo { height: 27px; margin-bottom: 15px; }
    .tn-head { font-size: 29px; }
    .tn-orb { width: 48px; height: 48px; margin: -24px 0 0 -24px; }
    .tn-orb span { font-size: 22px; }
}

@media (min-width: 992px) and (max-height: 800px) {
    .tn-shell { padding: 22px 22px 22px; gap: 16px; }
    .tn-top .tn-logo { display: none; }
    .tn-said { display: none; }
    .tn-foot { display: none; }
    .tn-head { font-size: 25px; margin-bottom: 0; }
    .tn-orb { width: 44px; height: 44px; margin: -22px 0 0 -22px; }
    .tn-orb span { font-size: 20px; }

    /* the card keeps every field, and only gives up a little air */
    .auth-form-card .mb-3 { margin-bottom: .85rem !important; }
    .auth-form-card .mb-4 { margin-bottom: 1.1rem !important; }
    .auth-new { margin-top: 16px; padding-top: 15px; }
}

@media (min-width: 992px) and (max-height: 680px) {
    .tn-shell { padding: 14px 20px 16px; gap: 12px; }
    .tn-head { font-size: 21px; }
    .tn-orb { width: 40px; height: 40px; margin: -20px 0 0 -20px; }
    .tn-orb span { font-size: 18px; }
}

/* On a hand-held the universe stays as the background and gets out of
   the way: two rings instead of three, no names, and the card is the
   page. */

@media (max-width: 991.98px) {
    .tn-shell { padding: 30px 18px 28px; gap: 24px; justify-content: flex-start; }
    .tn-top .tn-logo { height: 26px; margin-bottom: 14px; }
    .tn-head { font-size: 24px; }
    .tn-said { font-size: 13px; }
    .tn-mid { flex: 1 1 auto; align-items: flex-start; }
    .tn-orb { width: 40px; height: 40px; margin: -20px 0 0 -20px; }
    .tn-orb span { font-size: 18px; }
    .tn-orb b { display: none; }
    .tn-ring-1 { width: min(96vmin, 42vw); height: min(96vmin, 42vw); }
    .tn-ring-2 { width: min(124vmin, 54vw); height: min(124vmin, 54vw); }
    .tn-ring-3, .tn-ring-4, .tn-ring-5,
    .tn-arm-1, .tn-arm-3, .tn-arm-4, .tn-arm-5,
    .tn-orb.tn-r3, .tn-orb.tn-r4, .tn-orb.tn-r5,
    .tn-layer { display: none; }
    .tn-arm-2 { width: min(124vmin, 54vw); height: min(124vmin, 54vw); }
}

@media (max-width: 575.98px) {
    .tn-head { font-size: 21px; }
    .tn-said { font-size: 12.5px; }
    .tn-shell { padding: 24px 14px 24px; gap: 20px; }
}

@media (prefers-reduced-motion: reduce) {
    .tn-ring,
    .tn-arm,
    .tn-orb span { animation: none !important; }

    .tn-orb span { transition: none !important; }
}

@media (prefers-reduced-motion: reduce) {
    .tn-ring,
    .tn-arm,
    .tn-orb span { animation: none !important; }

    .tn-orb span { transition: none !important; }
}

/* ---------- owner's changes, 1 Sep 2026 ---------- */

/* Kept at the end, apart from the template's own rules, so the diff
   against template/tenant_template/modules/auth/css/auth.css stays one
   block rather than a scattering of edits nobody can find later. */

/* The mark on the card is the product's wordmark now, not a badge with an
   icon and a name beside it. `logo.svg` is 111x16, so a height alone keeps
   it in proportion. */
.auth-mark-logo {
    height: 18px;
    width: auto;
    display: block;
}

/* The terms row is gone from the sign-in card entirely (owner, 1 Sep
   2026) - consent belongs where an account is created, and platform staff
   do not self-register. `.auth-terms` still exists in the template's own
   rules above; nothing here overrides it any more. */

/* An invalid field is ONE box, not two (owner, 1 Sep 2026).

   The password keeps the theme's `.input-group.pass-group`, because the
   eye is the theme's own show-and-hide and `ui/js/script.js` finds its
   input with `closest('.input-group')`. Moving the eye out would break
   it.

   But an input group is two bordered cells, and Bootstrap's `.is-invalid`
   only reddens the input. The result was a red-bordered box welded to a
   grey-bordered one, which reads as a broken control rather than a wrong
   value. These rules carry the state across the whole group so it matches
   the email field beside it — which is a plain `.input-icon` and reddens
   as one rounded box.

   `:has()` because the state lives on the input and the addon is its
   sibling; there is no parent selector without it. */

/* `!important`, and it is not laziness. `style.css` line 6867 says

       .input-group-flat:focus-within .form-control,
       .input-group-flat:focus-within .input-group-text {
           border-color: var(--border-color) !important;
       }

   A failed submit focuses the first bad field, so the group IS
   `:focus-within` at exactly the moment it is invalid — and an `!important`
   beats any specificity. The rule below matched, parsed and loaded last,
   and still painted grey; only `!important` can answer `!important`.

   Both cells, so the control reads as one box: in a flat group the input
   has no right border and the addon carries the rest of the outline. */
body.signin-page .auth-form-card .input-group:has(> .form-control.is-invalid) > .form-control,
body.signin-page .auth-form-card .input-group:has(> .form-control.is-invalid) > .input-group-text {
    border-color: var(--bs-form-invalid-border-color, #dc3545) !important;
}

body.signin-page .auth-form-card .input-group:has(> .form-control.is-invalid) > .input-group-text {
    color: var(--bs-form-invalid-color, #dc3545);
}

/* Bootstrap paints its own warning glyph inside an invalid control. In an
   input group it lands under the eye, so the two overlap. The group already
   carries the message underneath and the red border above it; one icon is
   the field's, and it is the eye. */
body.signin-page .auth-form-card .input-group.pass-group > .form-control.is-invalid {
    background-image: none;
    padding-right: .75rem;
}

/* ---------------------------------------------------------------------
   Dark mode  ·  the sign-in screen

   The panel already honours a chosen theme; the door did not. Somebody
   working in dark signed out and was thrown a white page, then signed
   back in and it went dark again. The shell now loads `theme-script.js`
   like every other shell, and these are the two things that shell alone
   could not fix (owner, 1 Sep 2026).

   Everything else on this screen was already theme-aware: the card, the
   fields, the notice, the toast and the focus ring all come from
   Bootstrap variables that flip with `data-bs-theme`.
   --------------------------------------------------------------------- */

/* The page behind the card. The light version is four stacked gradients
   ending in a warm off-white; this is the same construction in the dark
   palette — the primary bloom kept, because it is what makes the screen
   ours rather than a generic dark rectangle, and the warm corner kept at
   lower strength so the composition does not collapse into flat black. */
[data-bs-theme="dark"] .signin-page {
    background:
        radial-gradient(48% 44% at 50% 46%, rgba(255, 255, 255, .05) 0%, rgba(255, 255, 255, 0) 68%),
        radial-gradient(70% 62% at 50% 50%, rgba(var(--primary-rgb), .16) 0%, transparent 66%),
        radial-gradient(60% 50% at 92% 96%, rgba(255, 162, 1, .10) 0%, transparent 62%),
        linear-gradient(178deg, #17161c 0%, #131519 52%, #1b1712 100%);
}

/* The mark. The wordmark is dark ink — on the dark card it was a smudge.
   `logo-white.svg` is what the template ships for this, and the two are
   swapped rather than recoloured so neither is ever half-legible.

   Scoped to `.auth-mark` on purpose: the template's own `.auth-brand`
   rules invert the names (`.logo-dark` is the one shown in LIGHT mode),
   and inheriting that confusion into a second place is how it becomes
   permanent. */
.auth-mark .logo-light { display: inline-block; }
.auth-mark .logo-dark { display: none; }

[data-bs-theme="dark"] .auth-mark .logo-light { display: none; }
[data-bs-theme="dark"] .auth-mark .logo-dark { display: inline-block; }

/* The refusal notice, when the refusal has something to say.

   Bootstrap's `.alert-dismissible` takes the close button out of the flow and
   pins it to the top right, then reserves room with `padding-right: 3rem`. Our
   bar is a flex row with an icon and `ms-auto` on the button, so the reserved
   room sits on the wrong side of the layout and a message long enough to wrap
   runs underneath the cross — which is exactly what the locked wording does
   (M2 SB3 T1, 2 Sep 2026): "…too man✕ failed attempts".

   Putting the button back in the flow is the whole fix. Nothing moves for the
   one-line messages that were there before. */
[data-sign-in-notice].alert-dismissible {
    padding-right: 1rem;
}

[data-sign-in-notice].alert-dismissible .btn-close {
    position: static;
    padding: .25rem;
    margin-top: .125rem;
    flex: 0 0 auto;
}
