/* auth.css — the screen layer for the five auth documents (/login /signup /verify /forgot
   /reset), hand-owned like app-components.css. Copied from the V5 design's auth screen layer
   (sas-product-design-v5/project/screens/auth.html:325-425) with ONE structural adaptation,
   marked below: the design draws .authpage as a bordered demo frame inside a review document;
   in the product the page IS the viewport, so the frame's border goes and the min-height
   becomes the real viewport. Everything else is verbatim, tokens only.

   The component pieces the auth cards use — .pinbox .pinnote .pw .pw-toggle .turnstile
   .reasonline .countdown .linkbtn .btn-block .btn-lg .field-req — are in components.css
   already (the design synced them there in V5); nothing auth-specific remains for them here. */

/* ── the page ── (adapted: the design frames this at min-height:560px with a border for its
   review doc; the product page is the viewport itself, so 100dvh and no frame) */
.authcanvas{margin:0;background:var(--canvas)}
.authpage{display:flex;align-items:center;justify-content:center;min-height:100dvh;background:var(--canvas);padding:var(--sp-6)}
.authpage-split{display:grid;grid-template-columns:minmax(0,420px) minmax(0,1fr);gap:var(--sp-6);align-items:center;justify-items:center}

/* ── the card ── */
.authcard{background:var(--surface);border:1px solid var(--hairline);border-radius:var(--r-xl);box-shadow:var(--shadow-raised);padding:var(--sp-6);display:flex;flex-direction:column;gap:var(--sp-5);width:100%}
/* Two widths, because the product has two: the forms are 380, the code and reset panels 420. */
.w-form{max-width:380px}
.w-code{max-width:420px}
.authhead{display:flex;flex-direction:column;gap:var(--sp-2)}
.brandmark{display:flex;align-items:center;gap:var(--sp-2);margin-bottom:var(--sp-1)}
.brandmark-logo{width:28px;height:28px;border-radius:var(--r-md);background:var(--accent-action);color:var(--accent-on-fill);display:grid;place-items:center;font-weight:var(--fw-bold);font-size:var(--fs-md)}
.brandmark-name{font-size:var(--fs-md);font-weight:var(--fw-semibold);letter-spacing:var(--tr-lg)}
.auth-title{margin:0;font-size:var(--fs-xl);line-height:var(--lh-xl);letter-spacing:var(--tr-xl);font-weight:var(--fw-semibold);color:var(--ink)}
.auth-sub{margin:0;font-size:var(--fs-sm);line-height:1.55;color:var(--ink-quiet)}
.auth-sub strong{color:var(--ink-body)}
.authbody{display:flex;flex-direction:column;gap:var(--sp-4)}
.authfoot{display:flex;flex-direction:column;gap:var(--sp-2);padding-top:var(--sp-4);border-top:1px solid var(--hairline-soft);font-size:var(--fs-sm);color:var(--ink-quiet)}
.authfoot-row{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap}

/* ── the signed-out marketing panel: static illustrative copy, no live data ── */
.promo{max-width:420px;display:flex;flex-direction:column;gap:var(--sp-4);padding:var(--sp-5);border:1px solid var(--hairline);border-radius:var(--r-lg);background:var(--surface)}
.promo-eyebrow{font-size:var(--fs-micro);letter-spacing:var(--tr-micro);text-transform:uppercase;font-weight:var(--fw-semibold);color:var(--ink-quiet)}
.promo-title{margin:0;font-size:var(--fs-lg);line-height:var(--lh-lg);font-weight:var(--fw-semibold);color:var(--ink)}
.promo-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-3)}
.promo-item{display:flex;gap:var(--sp-3);align-items:flex-start;font-size:var(--fs-sm);line-height:1.5;color:var(--ink-body)}
.promo-item svg{flex-shrink:0;margin-top:2px;color:var(--accent-text)}
.promo-note{margin:0;font-size:var(--fs-micro);line-height:1.6;color:var(--ink-quiet)}

/* ── item 21 · auth is exempt from the 1024px floor: responsive to 360px ── */
@media (max-width:900px){
  .authpage-split{grid-template-columns:minmax(0,1fr)}
  .promo{display:none}          /* marketing column drops first — the form is the job */
}
@media (max-width:480px){
  .authpage{padding:var(--sp-4);min-height:100dvh}
  .authcard{width:100%;max-width:100%;padding:var(--sp-5)}
  .pinrow{gap:var(--sp-2)}
  .pinbox{width:100%;max-width:64px;height:52px;font-size:var(--fs-lg)}
}

/* ── item 22 · an email is valid to 254 characters and contains no spaces ── */
.auth-sub,.banner-title,.banner-text,.panel-hint,.field-error{overflow-wrap:anywhere}
.addr{font-weight:var(--fw-semibold);color:var(--ink-body);overflow-wrap:anywhere}
.addr-trunc{display:inline-block;max-width:100%;vertical-align:bottom;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;text-align:left}

/* Spacing utilities — design v5 auth.html:484-487, used inside the drawn card markup
   (secondary submits under a PIN row and banner-to-title gaps). */
.mt-2{margin-top:var(--sp-2)}
.mt-3{margin-top:var(--sp-3)}
.mt-4{margin-top:var(--sp-4)}
.mt-5{margin-top:var(--sp-5)}

/* cf-turnstile is CLOUDFLARE's mount hook, not a style: their api.js queries this exact class
   and mounts the widget iframe inside it (with data-sitekey read off the same element). All of
   OUR styling for the slot lives on .turnstile in components.css. Declared empty here so the
   class-vocabulary gate keeps meaning "every class is accounted for in a sheet the page loads". */
.cf-turnstile{}

/* ── item 23 · the busy state must survive prefers-reduced-motion ── */
@media (prefers-reduced-motion:reduce){
  .btn.is-loading .btn-label{opacity:1}
  .btn.is-loading::after{display:none}
  .btn.is-loading .btn-static{display:inline-block}
}
.btn-static{display:none;width:8px;height:8px;margin-left:var(--sp-2);border-radius:2px;background:currentColor;opacity:.7}
