/* ==========================================================================
   THE SIGN-IN SCREEN — auth/login.blade.php only.

   It lived in om-clinic.css, which twelve documents link and eleven of them
   have no sign-in screen. Here it is charged to the one document that renders
   it, which is also the one document in the tree with real budget headroom.

   THREE COMPOSITIONS, not one that scales. The bands are the app's own —
   mobile <=767, tablet 768-1024, desktop >=1025 (DetectDeviceMiddleware,
   correctViewportHint) — because a width query that lands anywhere else is how
   this programme has found four breakpoints that did not match their shell.

     phone    a full-bleed brand hero with the form rising over it as a sheet
     tablet   one centred column: brand banner, three feature tiles ACROSS, form
     desktop  the two-panel split, brand beside form

   The clinic's own colour reaches the first screen anyone sees: the brand
   ground is --sidebar-bg, the token partials/theme redeclares per clinic.

   MOTION IS ONE ENTRANCE AND ONE AMBIENT DRIFT. The screen this replaced had
   three animated orbs and eight keyframed particles; that is what got it
   deleted. Everything here is off under prefers-reduced-motion.
   ========================================================================== */

@keyframes om-auth-rise{from{opacity:0;transform:translateY(1.5rem)}to{opacity:1;transform:none}}
@keyframes om-auth-fade{from{opacity:0}to{opacity:1}}
/* The wash crosses the panel once a minute. Slow enough to read as light
   rather than as animation, which is the difference between the two. */
@keyframes om-auth-drift{
  from{transform:translate3d(-8%,-6%,0) scale(1)}
  to{transform:translate3d(8%,6%,0) scale(1.25)}
}

.om-auth{display:grid;place-items:center;min-height:100vh;padding:var(--space-5);background:var(--bg-base)}
.om-auth__card{display:grid;grid-template-columns:minmax(0,11fr) minmax(0,14fr);max-width:64rem;width:100%;overflow:hidden;border-radius:var(--radius-xl);background:var(--surface);box-shadow:var(--shadow-2xl);animation:om-auth-rise var(--motion-slow) var(--ease-out) both}
.om-auth__brand{position:relative;display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-6);padding:var(--space-7) var(--space-6);background:var(--sidebar-bg);color:var(--text-inverse);overflow:hidden}
/* Two washes: one fixed key light, one that drifts. Both are pointer-inert and
   sit under .om-auth__brand>* (below), which is the only reason the panel's
   text is legible over them. */
.om-auth__brand::before,
.om-auth__brand::after{content:"";position:absolute;inset:-25%;pointer-events:none}
.om-auth__brand::before{background:radial-gradient(18rem 18rem at 20% 26%,var(--white-a08),transparent 70%)}
.om-auth__brand::after{background:radial-gradient(24rem 24rem at 78% 82%,var(--white-a10),transparent 65%);animation:om-auth-drift 48s var(--ease-in-out) infinite alternate}
.om-auth__brand>*{position:relative}
.om-auth__head{display:flex;align-items:center;gap:var(--space-3)}
.om-auth__mark{display:grid;place-items:center;flex:none;width:2.875rem;height:2.875rem;border-radius:var(--radius-md);background:var(--white-a18);border:1px solid var(--white-a22);font-size:1.35rem}
.om-auth__mark img{width:100%;height:100%;border-radius:var(--radius-md);object-fit:contain}
.om-auth__wordmark{margin:0;font:var(--fw-black) var(--fs-xl)/1.2 var(--font-sans);color:var(--text-inverse)}
.om-auth__title{margin:0 0 var(--space-3);font:var(--fw-black) var(--fs-2xl)/1.4 var(--font-sans);color:var(--text-inverse);text-wrap:balance}
.om-auth__desc{margin:0;max-width:26rem;font:var(--fw-regular) var(--fs-sm)/1.7 var(--font-sans);color:var(--white-a82)}
.om-auth__list{display:flex;flex-direction:column;gap:var(--space-3);margin:var(--space-5) 0 0;padding:0;list-style:none}
.om-auth__item{display:flex;align-items:center;gap:var(--space-3);font:var(--fw-semibold) var(--fs-xs)/1.55 var(--font-sans)}
.om-auth__item>span{display:grid;place-items:center;flex:none;width:2.25rem;height:2.25rem;border-radius:var(--radius-sm);background:var(--white-a10);border:1px solid var(--white-a18)}
.om-auth__foot{margin:0;font:var(--type-caption);color:var(--white-a62)}
.om-auth__form{display:flex;flex-direction:column;justify-content:center;gap:var(--space-4);padding:var(--space-7) var(--space-6)}
/* Start-aligned, not centred: it sits over a column of start-aligned fields, and
   a heading centred above them floats free of the thing it introduces. The phone
   hero above IS centred — that is a different block with nothing beside it. */
.om-auth__greet{margin:0;font:var(--fw-black) var(--fs-xl)/1.3 var(--font-sans);color:var(--ink)}
.om-auth__sub{margin:var(--space-1) 0 0;font:var(--type-caption);color:var(--ink-muted)}
/* The <form> owns its own rhythm: a flex column with a gap, so no control needs
   a margin nudge to sit right. @csrf is display:none and contributes no box. */
.om-auth__form form{display:flex;flex-direction:column;gap:var(--space-4)}
/* The screen arrives top-down, a beat behind the card. Written once against the
   two levels rather than per control. */
.om-auth__form>*,
.om-auth__form form>*{animation:om-auth-rise var(--motion-slow) var(--ease-out) both}
.om-auth__form form{animation:none}
.om-auth__form>:nth-child(1){animation-delay:60ms}
.om-auth__form>:nth-child(n+2){animation-delay:120ms}
.om-auth__form form>:nth-child(2){animation-delay:180ms}
.om-auth__form form>:nth-child(3){animation-delay:230ms}
.om-auth__form form>:nth-child(n+4){animation-delay:280ms}
/* ------------------------------------------------------------------ FIELD
   Both rows are one shape: glyph inside the control, label floating over it.
   The email field used to take x-field, which puts `icon` on the LABEL, while
   the password row has always carried its lock in the control — so the two
   fields on the first screen anyone sees were built two different ways.

   The float reads :placeholder-shown, which is the only empty-test that also
   catches autofill. Every input here therefore carries placeholder=" ". */
.om-authfield{display:flex;flex-direction:column;gap:var(--space-15)}
.om-authfield .om-input{block-size:3.5rem;padding-inline:var(--space-4);gap:var(--space-3)}
/* The stack exists so the label can be positioned against the INPUT rather than
   the row — no rule here has to know how wide the glyph is, or that the password
   row has a button on its far side and the email row does not. */
.om-authfield__stack{position:relative;flex:1;min-inline-size:0;display:flex;align-items:flex-end;
  block-size:100%;padding-block:var(--space-5) var(--space-2)}
.om-authfield__stack>input{inline-size:100%;min-inline-size:0;border:0;outline:none;background:transparent;
  font:var(--fw-medium) var(--fs-sm)/1.2 var(--font-sans);color:var(--ink)}
.om-authfield__label{position:absolute;inset-inline-start:0;inset-block:0;display:flex;align-items:center;
  margin:0;pointer-events:none;font:var(--fw-medium) var(--fs-sm)/1 var(--font-sans);color:var(--ink-faint);
  transition:transform var(--motion-base) var(--ease-out),font-size var(--motion-base) var(--ease-out),
             color var(--motion-fast) var(--ease-out)}
/* Floated: focused, or holding a value. font-size rather than a scale() —
   transform-origin takes no logical keyword, so a scaled label would fly off the
   wrong edge the moment this screen renders in a left-to-right language. */
.om-authfield .om-input:focus-within .om-authfield__label,
.om-authfield__stack>input:not(:placeholder-shown)~.om-authfield__label{
  transform:translateY(-0.8rem);font-size:var(--fs-2xs);color:var(--primary)}
/* The glyph answers the focus with the label. --icon-tab is small for a 3.5rem
   control; it grows to meet it. */
.om-authfield .om-input__icon{font-size:1.05rem;transition:color var(--motion-fast) var(--ease-out),
  transform var(--motion-base) var(--ease-spring)}
.om-authfield .om-input:focus-within .om-input__icon{transform:scale(1.12)}
/* Chrome paints -webkit-autofill with its own yellow and ignores background —
   an inset shadow the size of the field is the only thing that covers it, and
   the 9999s transition stops it repainting on blur. */
.om-authfield__stack>input:-webkit-autofill,
.om-authfield__stack>input:-webkit-autofill:hover,
.om-authfield__stack>input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--ink);box-shadow:0 0 0 40px var(--surface) inset;
  transition:background-color 9999s ease-in-out 0s}
.om-authfield__caps{display:flex;align-items:center;gap:var(--space-15);margin:0;
  padding-inline-start:var(--space-1);font:var(--type-caption);color:var(--warning);
  animation:om-rise-sm var(--motion-fast) var(--ease-out)}

/* The reveal button sits INSIDE .om-input, which is the flex row the kit already
   uses for prefix/suffix affixes — so the ring on :focus-within still surrounds
   the whole control rather than the button alone. */
.om-auth__reveal{display:grid;place-items:center;flex:none;width:var(--tap-min);height:var(--tap-min);border:0;background:none;color:var(--ink-faint);cursor:pointer;transition:var(--t-color)}
.om-auth__reveal:hover{color:var(--primary)}
.om-auth__reveal:active{transform:scale(var(--press-scale))}

/* A rejected sign-in shakes the form once. The alert says WHAT went wrong; this
   says the screen heard you, at the moment the page comes back looking identical
   to the one just submitted. */
@keyframes om-auth-shake{
  20%{transform:translateX(-0.4rem)}40%{transform:translateX(0.35rem)}
  60%{transform:translateX(-0.2rem)}80%{transform:translateX(0.15rem)}
  100%{transform:none}
}
.om-auth__form form.is-rejected{animation:om-auth-shake 480ms var(--ease-out)}

/* ----------------------------------------------------------------- TABLET
   768-1024, both ways up. The panel is shorter than a desktop's, so the three
   facts become TILES rather than plain rows — the same information, sized for
   the panel it is actually in. */
@media (min-width:768px) and (max-width:1024px){
  .om-auth{padding:var(--space-4)}
  .om-auth__brand{gap:var(--space-4);padding:var(--space-6) var(--space-5)}
  .om-auth__title{font-size:var(--fs-xl);margin-bottom:var(--space-2)}
  .om-auth__desc{max-width:none}
  .om-auth__list{gap:var(--space-2);margin-top:var(--space-3)}
  .om-auth__item{padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);background:var(--white-a08);border:1px solid var(--white-a10)}
  .om-auth__form{padding:var(--space-6) var(--space-5)}
}

/* -------------------------------------------------------- TABLET, UPRIGHT
   Upright it ran the desktop split scaled down: a 380px form and a 300px
   argument in a card floating in 250px of dead space top and bottom. One column
   instead, and the tiles turn ACROSS — icon over label — which is the shape
   that uses a tablet's width.

   ORIENTATION is what decides, not width. MEASURED: this stacked card is 833px
   tall. That fits every upright tablet (1024, 1112) and puts the submit button
   65px BELOW THE FOLD on a 1024x768 one held sideways, which keeps the split. */
@media (min-width:768px) and (max-width:1024px) and (orientation:portrait){
  .om-auth{padding:var(--space-6) var(--space-5)}
  .om-auth__card{grid-template-columns:minmax(0,1fr);max-width:34rem}
  .om-auth__brand{padding:var(--space-6)}
  .om-auth__list{flex-direction:row}
  .om-auth__item{flex:1;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-2);font-size:var(--fs-2xs);text-align:center}
  .om-auth__foot{padding-top:var(--space-3);border-top:1px solid var(--white-a10)}
  .om-auth__form{padding:var(--space-6)}
}

/* ------------------------------------------------------------------ PHONE
   A splash and a sheet. The hero is centred — the one place on this screen
   where centring is right, because there is nothing beside it to align to —
   and the form lifts over it with a grabber, which is what every app the user
   already has does with a panel that slides up.

   D14: the dynamic inset reaches padding only through --safe-max-inset-bottom,
   the STATIC token. env() appears nowhere on this screen. */
@media (max-width:767px){
  .om-auth{padding:0;align-items:stretch}
  .om-auth__card{grid-template-columns:minmax(0,1fr);max-width:none;min-height:100vh;border-radius:0;box-shadow:none;animation:none}
  /* One splash, not two halves. The base panel is space-between, which on a
     phone pins the wordmark to the ceiling and the promise to the floor with a
     hole between them; here they are one group. */
  .om-auth__brand{justify-content:center;gap:var(--space-4);padding:var(--space-7) var(--space-4) var(--space-6);text-align:center;animation:om-auth-fade var(--motion-slow) var(--ease-out) both}
  .om-auth__head{flex-direction:column;gap:var(--space-2)}
  .om-auth__mark{width:3.5rem;height:3.5rem;font-size:1.7rem}
  .om-auth__title{font-size:var(--fs-lg);margin-bottom:0}
  .om-auth__desc{max-width:none}
  .om-auth__list,.om-auth__foot{display:none}
  .om-auth__form{position:relative;margin-top:calc(var(--space-6) * -1);padding:var(--space-6) var(--space-4) calc(var(--space-6) + var(--safe-max-inset-bottom));border-radius:var(--radius-xl) var(--radius-xl) 0 0;background:var(--surface);animation:om-auth-rise var(--motion-slow) var(--ease-out) both}
  .om-auth__form::before{content:"";position:absolute;inset-block-start:var(--space-3);inset-inline:0;width:2.5rem;height:0.25rem;margin-inline:auto;border-radius:var(--radius-pill);background:var(--border)}
  .om-auth__greet{padding-top:var(--space-3)}
}

@media (prefers-reduced-motion:reduce){
  .om-auth__card,.om-auth__brand,.om-auth__brand::after,.om-auth__form>*,.om-auth__form form>*,
  .om-auth__form form.is-rejected,.om-authfield__caps{animation:none}
  .om-authfield .om-input:focus-within .om-input__icon{transform:none}
}

/* om-install — the offer, revealed by public/js/offline/install.js.
   HERE and not om-kit.css: om-kit is linked by twelve authenticated documents
   that can never render this, and measured 948 gz on each of them.
   Never `display:none` — the module toggles the `hidden` ATTRIBUTE, and a rule
   here would beat it silently. Rationale: partials/install-offer.blade.php. */
.om-install {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    margin-block-start: var(--space-4);
    border: var(--hairline) solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-soft);
}

.om-install__icon {
    display: grid;
    place-items: center;
    flex: none;
    inline-size: var(--space-6);
    block-size: var(--space-6);
    border-radius: var(--radius-md);
    background: var(--primary-soft);
    color: var(--primary);
    font-size: var(--fs-sm);
}

.om-install__text { display: grid; gap: var(--space-05); min-inline-size: 0; }
.om-install__title { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--ink); }
.om-install__sub { font-size: var(--fs-xs); color: var(--ink-muted); }

.om-install__action { flex: none; margin-inline-start: auto; }

.om-install__dismiss {
    flex: none;
    display: grid;
    place-items: center;
    inline-size: var(--tap-min);
    block-size: var(--tap-min);
    border: 0;
    background: transparent;
    color: var(--ink-faint);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out);
}
.om-install__dismiss:hover { color: var(--ink); background: var(--surface-sunken); }

/* On a phone the row becomes a stack: at 360px an icon, two lines of Arabic, a
   button and a close target cannot share a row without the text column falling
   below a readable width. The dismiss stays on the first line with the title —
   it is the control someone reaches for without reading. */
/* 30em, not 480px. Raw px is a lint error everywhere in this sheet and the six
   breakpoints that predate it are baseline debt, not a licence. An em breakpoint
   is also the right unit here: this is a wrap point for one component's own text,
   so it should move when the reader's font size does, unlike the 767/1024 device
   bands, which mirror om-shell.js and must stay in px. */
@media (max-width: 30em) {
    .om-install { flex-wrap: wrap; }
    .om-install__text { flex: 1 1 60%; }
    .om-install__action { inline-size: 100%; margin-inline-start: 0; order: 1; }
}
