/* The sign-in page, design A, and the session check that runs before it (ticket 113).
   Loaded by index.html and backoffice.html after app.css (and after backoffice.css) so
   these rules win over the shell's. It styles the signed-out states and nothing else.
   Every value is a token from finance_app/static/tokens.css; this sheet defines none of
   its own and holds no literal colour, size, radius or duration.

   The page has three states, and <body data-auth> is which one:
     checking  the client has asked GET /api/session and has no answer yet
     out       the server said nobody is signed in, so the form is on screen
     in        the server confirmed a session, so the app shell is on screen
   Nothing here reads a browser-side flag: app.js sets the attribute from the server's
   answer and from nothing else, and the markup ships as "checking". */

/* --- The shell steps aside while nobody is signed in. ---------------------------- */
/* app.css already drops the sidebar, breadcrumb and company for a hidden #workspace.
   The rest of the chrome goes too: design A gives the whole viewport to the two panels
   and the brand belongs on the green one. What stays is the language switch, which an
   operator needs BEFORE reading the form; it floats over the form panel's top corner so
   the green panel still reaches the top of the viewport. */
body:not([data-auth=in]) main{inline-size:100%;max-inline-size:none;margin:0;padding:0;flex:1 1 auto;display:flex;flex-direction:column}
body:not([data-auth=in]) .app-column{position:relative}
body:not([data-auth=in]) .topbar{position:absolute;inset-block-start:0;inset-inline-end:0;inline-size:auto;min-block-size:0;padding:var(--space-16);background:transparent;border-block-end:0;z-index:var(--z-sticky)}
/* app.css puts the brand back into the top bar whenever #workspace is hidden, at a
   specificity its `:has(#workspace[hidden])` gives it; this has to carry the same `:has`
   plus the state attribute to outrank it. On the sign-in page the brand is on the green
   panel, where design A puts it, so the top bar shows it a second time otherwise. */
body:has(#workspace[hidden]):not([data-auth=in]) .topbar .brand,
body:not([data-auth=in]) .topbar .top-actions>:not(.language-switch){display:none}
body.backoffice:not([data-auth=in]){display:flex;flex-direction:column;min-block-size:100vh;position:relative}
body.backoffice:not([data-auth=in]) .bo-topbar{position:absolute;inset-block-start:0;inset-inline-end:0;block-size:auto;padding:var(--space-16);background:transparent;border-block-end:0;z-index:var(--z-sticky)}
body.backoffice:not([data-auth=in]) .bo-brand{display:none}
body.backoffice:not([data-auth=in]) main{padding:0;flex:1 1 auto;display:flex;flex-direction:column}

/* --- Checking a session: one state, before anything else paints. ------------------ */
.session-check{flex:1 1 auto;display:flex;align-items:center;justify-content:center;padding:var(--space-32) var(--space-16)}
.session-check-card{display:flex;flex-direction:column;align-items:center;gap:var(--space-16);text-align:center;max-inline-size:var(--size-280)}
.session-spinner{inline-size:var(--size-36);block-size:var(--size-36);border:var(--size-marker) solid var(--color-border-default);border-block-start-color:var(--color-action-primary);border-radius:var(--radius-pill);animation:session-spin calc(var(--duration-slow)*4) linear infinite}
@keyframes session-spin{to{transform:rotate(360deg)}}
.session-check p{margin:0;color:var(--color-text-secondary)}
.session-retry{display:flex;flex-direction:column;align-items:center;gap:var(--space-12)}
.session-retry p{color:var(--color-feedback-warning-text)}
/* Nothing is in flight once the retry is offered, so the spinner stops turning. A
   spinner over a "could not reach the server" line says two different things at once. */
.session-check:has(#session-retry:not([hidden])) .session-spinner{display:none}
@media (prefers-reduced-motion:reduce){.session-spinner{animation:none}}

/* --- Design A: brand and story on the left, the form on the right. ---------------- */
.login-page{flex:1 1 auto;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-inline-size:0}
.login-story{display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-48);min-inline-size:0;padding:var(--space-48) var(--space-64);background:var(--color-action-primary-hover);color:var(--color-text-on-primary)}
.login-brand{display:flex;align-items:center;gap:var(--space-12);min-inline-size:0;font-size:var(--text-xl);font-weight:var(--weight-semibold);line-height:var(--leading-snug)}
.login-brand-mark{display:grid;place-items:center;inline-size:var(--size-48);block-size:var(--size-48);flex:0 0 auto;border:var(--size-hairline-strong) solid currentColor;border-radius:var(--radius-card);font-size:var(--text-xl)}
.login-brand-copy{display:flex;flex-direction:column;min-inline-size:0}
.login-brand-sub{font-size:var(--text-xs);font-weight:var(--weight-regular);letter-spacing:.12em;text-transform:uppercase}
.login-overline{margin:0 0 var(--space-16);font-size:var(--text-base);color:inherit}
.login-story h1{margin:0;font-size:var(--text-display-sm);line-height:var(--leading-normal);font-weight:var(--weight-semibold);letter-spacing:normal;color:inherit}
.login-story-description{margin:var(--space-20) 0 0;color:inherit;max-inline-size:56ch}
.login-story-footer{margin:0;font-size:var(--text-sm);color:inherit}
/* TICKET 153 (SB-29): the story heading, the line under it and the help text each break
   between their two phrases, where design A breaks them, rather than wherever the width
   happens to fall (the heading used to break inside "เห็น / วงเงิน"). */
.login-line{display:block}

/* The illustration. Every figure in it is a fixed example, not this stage's data, and the
   whole block is aria-hidden so no one is read a number that means nothing. */
.login-figure{margin-block-start:var(--space-40);padding:var(--space-24) var(--space-28);max-inline-size:calc(var(--space-64)*7);background:var(--color-surface-card);color:var(--color-text-primary);border-radius:var(--radius-card);box-shadow:var(--shadow-sm)}
.login-figure-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-12);font-size:var(--text-base)}
.login-figure-tag{padding:var(--space-4) var(--space-10);font-size:var(--text-sm);background:var(--color-surface-selected);color:var(--color-action-primary);border-radius:var(--radius-pill)}
.login-figure-label{margin:var(--space-24) 0 0;font-size:var(--text-sm);color:var(--color-text-secondary)}
.login-figure-amount{font-size:var(--text-display-sm);font-weight:var(--weight-semibold);font-variant-numeric:tabular-nums;line-height:var(--leading-normal);color:var(--color-action-primary-hover)}
.login-figure-amount small{margin-inline-start:var(--space-12);font-size:var(--text-base);font-weight:var(--weight-regular)}
.login-figure-meter{block-size:var(--space-6);margin-block-start:var(--space-16);background:var(--color-meter-track);border-radius:var(--radius-pill);overflow:hidden}
.login-figure-meter span{display:block;inline-size:27%;block-size:100%;background:var(--color-meter-fill)}
.login-figure-caption{display:flex;justify-content:space-between;gap:var(--space-8);margin-block-start:var(--space-8);font-size:var(--text-xs);color:var(--color-text-secondary)}
.login-figure-foot{display:flex;align-items:center;gap:var(--space-12);margin-block-start:var(--space-24);padding-block-start:var(--space-20);border-block-start:1px solid var(--color-border-default);font-size:var(--text-sm);color:var(--color-text-secondary)}
.login-figure-foot strong{display:block;font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text-primary)}
.login-figure-icon{display:grid;place-items:center;inline-size:var(--size-40);block-size:var(--size-40);flex:0 0 auto;background:var(--color-surface-selected);color:var(--color-action-primary);border-radius:var(--radius-control)}
.login-figure-check{display:grid;place-items:center;margin-inline-start:auto;flex:0 0 auto;color:var(--color-action-primary)}

/* --- The form panel. -------------------------------------------------------------- */
.login-panel{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-48);min-inline-size:0;padding:var(--space-64);background:var(--color-surface-card)}
.login-form-wrap{inline-size:100%;min-inline-size:0;max-inline-size:calc(var(--space-64)*6 + var(--space-16));margin-block:auto}
.login-form-overline{margin:0 0 var(--space-8);font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-action-primary)}
.login-form-wrap h1{margin:0;font-size:var(--text-xxl);font-weight:var(--weight-semibold);line-height:var(--leading-normal);letter-spacing:normal}
.login-form-description{margin:var(--space-8) 0 var(--space-32)}
#login-form{display:block;padding:0}
.login-field{display:block;margin-block-end:var(--space-24)}
.login-field label{display:block;flex:none;margin-block-end:var(--space-8);font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--color-text-primary)}
.login-field input{display:block;inline-size:100%;min-inline-size:0;min-block-size:var(--size-48);padding:var(--space-12) var(--space-16);font-size:var(--text-md)}
/* TICKET 153 (SB-28): an invalid field is outlined in the destructive red design A uses.
   The pale danger border it replaces measures 1.90:1 on the white field (scripts/
   contrast.py), under the 3:1 a control's state needs (WCAG 1.4.11); this one 6.47:1. */
.login-field input[aria-invalid=true]{border-color:var(--color-action-destructive)}
.login-password{position:relative}
.login-password input{padding-inline-end:var(--size-48)}
.login-password button{position:absolute;inset-inline-end:var(--space-4);inset-block-start:50%;transform:translateY(-50%);display:grid;place-items:center;inline-size:var(--size-44);block-size:var(--size-44);min-block-size:0;padding:0;background:transparent;border-color:transparent;border-radius:var(--radius-control);color:var(--color-text-secondary)}
.login-password button:hover{background:var(--color-action-ghost-hover);border-color:transparent;color:var(--color-text-primary)}
.login-password button:active{transform:translateY(-50%)}
.login-password button .icon-hide{display:none}
.login-password button[aria-pressed=true] .icon-show{display:none}
.login-password button[aria-pressed=true] .icon-hide{display:block}
.login-hint{margin:var(--space-8) 0 0;font-size:var(--text-base);color:var(--color-text-secondary)}
.login-error{margin:0 0 var(--space-20);padding:var(--space-12) var(--space-16);font-size:var(--text-base);background:var(--color-feedback-error-bg);color:var(--color-feedback-error-text);border:1px solid var(--color-border-danger);border-radius:var(--radius-control);max-inline-size:none}
/* In flight, the submit is LOCKED but not dimmed: a request being carried out is not the
   same message as "you may not do this", and reusing the disabled look says the wrong one.
   It is still `disabled`, which is what stops a second press. */
.login-submit{display:flex;align-items:center;justify-content:center;gap:var(--space-12);inline-size:100%;min-block-size:var(--size-48);padding:var(--space-12) var(--space-20)}
.login-submit .button-spinner{display:none}
.login-submit[aria-busy=true]:disabled{opacity:1;cursor:wait}
.login-submit[aria-busy=true] .button-spinner{display:inline-block}
.login-status{margin:var(--space-8) 0 0;font-size:var(--text-base);color:var(--color-text-secondary)}
.login-status:empty{margin:0}
.login-help{margin-block-start:var(--space-28);text-align:center;font-size:var(--text-base);color:var(--color-text-secondary)}
.login-help strong{display:block;font-weight:var(--weight-medium);color:var(--color-text-primary)}
.login-help p{margin:var(--space-4) auto 0;max-inline-size:44ch}
.login-footer{margin:0;font-size:var(--text-sm);color:var(--color-text-secondary);text-align:center}
.login-footer span{margin-inline-start:var(--space-16)}

/* --- Narrower than a desk: the form comes first and the story shrinks to a brand bar.
       The two widths are the prototype's own (login.css), kept so the break lands where
       the design puts it rather than where this sheet would guess. --- */
@media (max-width:980px){ /* ds-allow-hardcode: layout breakpoint from the design-A prototype */
  .login-story{padding:var(--space-32)}
  .login-panel{padding:var(--space-40) var(--space-32)}
  .login-story h1{font-size:var(--text-xxl)}
  .login-figure{padding:var(--space-20)}
  .login-figure-amount{font-size:var(--text-xxl)}
}
@media (max-width:700px){ /* ds-allow-hardcode: layout breakpoint from the design-A prototype */
  /* The brief: "มือถือเก็บแบรนด์สั้น ๆ และให้ฟอร์มอยู่ก่อนเนื้อหาตกแต่ง" -- keep a SHORT brand
     bar, and put the form before the DECORATIVE content. So the column reads brand bar,
     then the form, then the illustration and the story. The brand and that content are
     two ends of one element on the desktop, so at this width `.login-story` gives up its
     box (`display:contents`) and its three children become items of the same single
     column, which is what lets the form sit between them. An element with no box paints
     no background, so the green field is painted on the two pieces that keep one; they
     are adjacent, so it still reads as one field under the form. Colour is inherited
     through a contents box, so the ink needs nothing. */
  .login-page{grid-template-columns:minmax(0,1fr)}
  .login-story{display:contents}
  .login-brand,.login-story-content,.login-story-footer{background:var(--color-action-primary-hover)}
  /* The language switch floats over the top right corner, which at this width is the
     brand bar; the reserved end padding keeps the wordmark out from under it. */
  .login-brand{order:1;padding:var(--space-24);padding-inline-end:calc(var(--space-64)+var(--space-48));font-size:var(--text-lg)}
  .login-brand-mark{inline-size:var(--size-40);block-size:var(--size-40)}
  .login-panel{order:2;padding:var(--space-32) var(--space-24);gap:var(--space-32)}
  .login-story-content{order:3;padding:var(--space-32) var(--space-24) var(--space-24)}
  .login-story-footer{order:4;padding:0 var(--space-24) var(--space-32)}
  .login-figure{margin-block-start:var(--space-24);max-inline-size:none}
}
@media (max-width:360px){ /* ds-allow-hardcode: the narrow guard this repo gates at 280/320 */
  .login-panel{padding-inline:var(--space-16)}
  .login-story{padding:var(--space-16)}
}
