/* Auth page structure (design-overhaul T1): this file now carries ONLY
   the rules paper.css doesn't cover -- page shell, mode tabs, form field
   layout, info/error boxes, the account chip -- and the Paper reskin.

   Console fix round 1 (2026-08-20, binding): every rule that SHAPES THE
   PAGE SHELL (body's flex/align/padding, `main.card`'s width cap,
   `.page-header`'s width cap) is scoped under `body.auth-page` so it
   applies ONLY to the three auth pages (signin.html, auth_landing.html,
   tos.html), which now carry `<body class="auth-page">`. Without this,
   these rules leaked onto every OTHER page that also links this file
   (console/albums/my_face/event/index) -- confirmed live: auth.css's
   unscoped `body { display:flex; align-items:center }` shrank console's
   nav/content to a ~390px column even though console.html's own inline
   `<style>` tried to override it (a flex `align-items:center` parent
   makes its block children shrink-to-fit instead of stretching full
   width). Token fallbacks and component classes (.btn-primary, .chip*,
   .error, .field, etc.) stay GLOBAL/unscoped -- console.html
   and index.html still use several of those. The one exception is the
   bare `form` selector, which shaped every form's flex layout globally;
   it's scoped to `.card form` below instead of `body.auth-page form` --
   .card is the auth-page card wrapper AND index.html's search-card, so
   that scoping is what the search form there already relies on, while
   correctly excluding index.html's inline intent-tile code form and
   console.html's non-`.card` forms (both were being wrongly forced into
   a column layout by the unscoped selector).

   Pre-merge correction: every page dual-loads paper.css THEN this file
   (true since T1-T3 shipped; an earlier version of this comment wrongly
   claimed event.html/console.html "load auth.css alone" -- that was only
   ever true mid-branch, before those tasks landed). This :root used to
   also declare `--soft`/`--line`, two legacy bare token names the same
   earlier comment claimed event.html/console.html's inline <style>
   blocks still read -- grep-verified zero consumers anywhere in
   app/static (they'd read `--hairline-2`/`--secondary` instead, which is
   what those blocks actually use); deleted rather than kept as dead
   weight (tightening batch, 2026-08-20). The OTHER names it re-declares
   (`--ground`, `--ink`, `--green`, `--radius`) ARE also in paper.css;
   because this file loads second, its
   copies win the cascade for any custom-property consumer that isn't
   using the `var(--token, <Paper literal>)` fallback pattern below --
   they MUST stay value-identical to paper.css's tokens, or the two files
   would silently diverge. This file's own rules read the Paper-named
   tokens via `var(--token, <Paper literal>)` regardless, so paper.css's
   :root is still the effective single source for anything this file
   doesn't also touch.
   One token stays local outright: --error, a red not in the locked Paper
   set (semantic green/amber only) -- form/login error states need it and
   paper.css deliberately doesn't invent it. */

:root {
  --ground: #FAFAF9;
  --ink: #18181B;
  --green: #15803D;
  --radius: 10px;
  /* Dark-mode batch (2026-08-20): indirected through paper.css's `--danger`
     token (defined with a light/dark pair there) rather than a bare
     literal -- `var(--danger)` resolves against whatever paper.css's :root
     cascade currently has active (system dark, or the `[data-theme]`
     toggle override), so this file doesn't need its own dark guard. The
     literal fallback stays for the same "paper.css might not have loaded
     yet" defensive posture as every other `var(--token, <literal>)` in
     this file (unreachable in practice -- paper.css always loads first). */
  --error: var(--danger, #C0392B);
  /* `light dark`, matching paper.css's :root -- this file's own `:root`
     rule loads AFTER paper.css's and would otherwise win the cascade
     (same specificity, later source) and silently pin native controls to
     light regardless of system/toggle state. paper.css's
     `:root[data-theme="light"|"dark"]` overrides still win over this
     (higher specificity), so the explicit toggle is unaffected either
     way -- this only matters for the "system" state. */
  color-scheme: light dark;
}

* { box-sizing: border-box; }

body.auth-page {
  background: var(--ground, #FAFAF9);
  color: var(--ink, #18181B);
  font-family: var(--font-sans, system-ui, -apple-system, "Segoe UI", Roboto,
    "PingFang SC", "Noto Sans SC", "Microsoft YaHei", "Noto Sans Thai",
    "Leelawadee UI", sans-serif);
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5rem 1rem 3rem;
}

body.auth-page .page-header {
  width: 100%;
  max-width: 420px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2.5rem;
}

.brand {
  font-weight: 600;
  font-size: 1.05rem;
  letter-spacing: -0.01em;
}

/* The native <select>-based language selector (formerly styled here via
   .lang-select) was replaced project-wide (design directive 2026-08-20:
   "language selector is always top right") by the custom Paper-menu
   dropdown component -- markup is a bare [data-lang-dropdown] marker,
   progressively enhanced by /static/i18n.js; styles live in paper.css's
   .lang-dropdown* rules (shared across every page, not auth-page-only). */

/* Audit P0: vertically centers the card in the remaining viewport space
   BELOW the header (the header stays pinned at top, not swept into the
   centering group) -- `margin: auto 0` on a flex-column item consumes
   whatever free space body.auth-page's `min-height: 100vh` leaves, no
   `justify-content` on the parent needed (that would center the header
   too). tos.html stops using main.card entirely (plain text document,
   this task) so this only visibly affects signin.html + auth_landing.html
   now, both of which want it. */
body.auth-page main.card {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin: auto 0;
}

h1 {
  font-size: 1.5rem;
  margin: 0;
  letter-spacing: -0.01em;
}

.trust {
  color: var(--secondary, #52525B);
  font-size: .85rem;
  margin: 0;
}

.mode-tabs {
  display: flex;
  gap: .5rem;
}

.mode-tabs button {
  flex: 1;
  padding: .55rem .8rem;
  border-radius: var(--radius, 10px);
  border: 1px solid var(--hairline-2, #E4E4E7);
  background: transparent;
  color: var(--secondary, #52525B);
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
}

.mode-tabs button[aria-selected="true"] {
  color: var(--ink, #18181B);
  border-color: var(--ink, #18181B);
  font-weight: 600;
}

.btn-primary {
  background: var(--ink, #18181B);
  color: var(--ground, #FAFAF9);
  border: none;
  border-radius: var(--radius, 10px);
  min-height: 44px;
  padding: .85rem 1.1rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  width: 100%;
  text-align: center;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.btn-primary:disabled {
  opacity: .55;
  cursor: default;
}

.btn-ghost {
  background: var(--card, #FFFFFF);
  color: var(--ink, #18181B);
  border: 1px solid var(--hairline-2, #E4E4E7);
  border-radius: var(--radius, 10px);
  min-height: 44px;
  padding: .7rem 1.1rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  width: 100%;
  text-align: center;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Audit P1: the Google sign-in button's icon+label spacing -- .google-g
   is decorative (aria-hidden) alongside a visible text label. */
.google-cta { gap: .6rem; }
.google-g { flex-shrink: 0; }

/* Social row (auth reskin, pinned reference layout): `flex: 1 1 0` on
   every child means this needs NO changes when Apple/LINE ship
   (founder-confirmed roadmap) -- one child (today) stretches to fill the
   row exactly like a plain full-width button; three children (the
   eventual Google/Apple/LINE 3-up, matching the reference mock's
   Apple/Facebook/Google row) split it evenly instead. `min-width` forces
   a narrow viewport to wrap to a stacked column rather than squeezing
   labels. */
.social-row {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
}

.social-row > a,
.social-row > button {
  flex: 1 1 0;
  min-width: 140px;
}

.divider {
  display: flex;
  align-items: center;
  gap: .75rem;
  color: var(--secondary, #52525B);
  font-size: .85rem;
}

.divider::before,
.divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--hairline-2, #E4E4E7);
}

/* Scoped to `.card form` (console fix round 1), not a bare `form`
   selector -- `.card` is the auth-page card wrapper AND index.html's
   search-card (`class="search-card card"`), which is exactly the set of
   forms meant to get this column layout. An unscoped `form` was landing
   on every form on every page: index.html's inline intent-tile code form
   (meant to be an inline input+button row, forced into a column instead)
   and console.html's non-`.card` forms alike -- neither wanted this. */
.card form {
  display: flex;
  flex-direction: column;
  gap: .85rem;
}

label {
  font-size: .85rem;
  color: var(--secondary, #52525B);
  display: block;
  margin-bottom: .3rem;
}

/* Kept in sync by hand with paper.css's identical selector (fix round 1,
   minor 4; pre-merge correction: every page dual-loads paper.css THEN
   this file, so this is a value-identical duplicate, not a fallback for
   pages that skip paper.css -- since this file loads second, its copy
   wins the cascade, so it MUST stay value-identical to paper.css's or the
   two would silently diverge). If you change one, change the other.
   E2E round 1, finding 3: type="url"/type="search" added alongside
   paper.css's (future-proof, no current auth-only field uses either).
   Tightening batch (2026-08-20): type="date" added alongside paper.css's
   own addition (console Settings' event-date field). */
input[type="email"],
input[type="password"],
input[type="text"],
input[type="url"],
input[type="search"],
input[type="date"] {
  width: 100%;
  padding: .7rem .8rem;
  font-size: 1rem;
  border: 1px solid var(--hairline-2, #E4E4E7);
  border-radius: var(--radius, 10px);
  background: var(--card, #FFFFFF);
  color: var(--ink, #18181B);
}

input:focus {
  outline: 2px solid var(--ink, #18181B);
  outline-offset: 1px;
}

.field {
  margin: 0;
}

/* Display name field's small helper caption, between the label and the
   input (auth reskin). */
.field-hint {
  font-size: .78rem;
  color: var(--muted, #A1A1AA);
  margin: 0 0 .35rem;
}

/* Password field wrapper: positions the eye toggle inside the input's
   right edge (auth reskin, both views). */
.password-field {
  position: relative;
}

.password-field input {
  padding-right: 2.75rem;
}

.password-toggle {
  position: absolute;
  top: 50%;
  right: .4rem;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--secondary, #52525B);
  cursor: pointer;
}

.password-toggle:hover {
  color: var(--ink, #18181B);
  background: var(--hairline, #EDEDEB);
}

/* Strength meter (signup only, auth reskin): 4 segments, unlit ->
   --hairline-2, lit -> --green -- see signin.html's scoreStrength() for
   the thresholds. aria-live text sits below the bars. */
.strength-meter {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin-top: .5rem;
}

.strength-bars {
  display: flex;
  gap: .35rem;
}

.strength-seg {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: var(--hairline-2, #E4E4E7);
  transition: background .15s ease;
}

.strength-seg.lit {
  background: var(--green, #15803D);
}

.strength-text {
  font-size: .78rem;
  color: var(--secondary, #52525B);
  min-height: 1em;
}

.link-row {
  display: flex;
  justify-content: flex-end;
  font-size: .85rem;
}

.link-row a,
.link-row button.link {
  color: var(--secondary, #52525B);
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}

.error {
  color: var(--error);
  font-size: .85rem;
  margin: 0;
}

.info {
  border: 1px solid var(--hairline-2, #E4E4E7);
  border-radius: var(--radius, 10px);
  padding: .9rem 1rem;
  font-size: .9rem;
  margin: 0;
}

.info.success {
  border-color: var(--green, #15803D);
}

.info.success .info-title {
  color: var(--green, #15803D);
  font-weight: 600;
  display: block;
  margin-bottom: .25rem;
}

.hidden {
  display: none !important;
}

/* Primary CTA pill (auth reskin, pinned reference layout): overrides
   .btn-primary's 10px --radius with a full pill (999px) for THIS button
   only, via the id selector -- .btn-primary itself stays untouched
   (global/unscoped class, still used at its normal 10px radius by
   auth_landing.html's reset-submit and every other .btn-primary
   consumer across the site). */
#auth-submit {
  border-radius: 999px;
}

/* Legal line under the CTA, signup only (auth reskin). */
.agree-line {
  font-size: .78rem;
  color: var(--secondary, #52525B);
  text-align: center;
  margin: 0;
}

.agree-line a {
  color: var(--ink, #18181B);
  text-decoration: underline;
}

/* Bottom cross-link (auth reskin): replaces the old tab pattern --
   "Already have an account? Log in" / "New here? Create an account". */
.cross-link {
  text-align: center;
  font-size: .9rem;
  color: var(--secondary, #52525B);
  margin: 0;
}

.cross-link button.link {
  color: var(--ink, #18181B);
  background: none;
  border: none;
  /* `font: inherit` is a shorthand that resets font-weight too -- it MUST
     come before the font-weight override below, or the override gets
     silently reset back to 400 (auth review polish, fix round 1). */
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}

.cta-row {
  display: flex;
  flex-direction: column;
  gap: .6rem;
}

#fm-account-chip:empty {
  display: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  position: relative;
  min-width: 0;
}

.chip-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--ink, #18181B);
  color: var(--ground, #FAFAF9);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
  border: none;
  flex-shrink: 0;
}

/* Dropdown restyle (console-sidebar batch, 2026-08-20): a header block
   (truncated email) then hairline-separated groups (My Face/Host
   console; verify-email/sign out), padded hover rows, min-width 240px.
   `overflow: hidden` + `text-overflow: ellipsis` (never `word-break:
   break-all`) on every row -- long text truncates with an ellipsis
   instead of wrapping mid-word. */
.chip-menu {
  position: absolute;
  top: 2.5rem;
  right: 0;
  /* Fix round 2 (founder screenshot): with no z-index, this positioned
     element stacked purely by DOM order among other positioned elements
     at the default z-index:auto -- the landing hero's .illus-tiles (also
     `position: relative`, but later in the DOM) painted over an open
     menu. A z-index this high only needs to clear same-page positioned
     content; it never competes with the guest camera/viewer's fixed
     full-bleed overlays (z-index 20/30), which live on a different page
     entirely. */
  z-index: 40;
  background: var(--card, #FFFFFF);
  border: 1px solid var(--hairline-2, #E4E4E7);
  border-radius: var(--radius, 10px);
  padding: .4rem;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  font-size: .85rem;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .08);
}

.chip-menu-header {
  padding: .5rem .6rem .65rem;
  margin-bottom: .3rem;
  border-bottom: 1px solid var(--hairline, #EDEDEB);
}

.chip-menu .chip-email {
  color: var(--secondary, #52525B);
  font-size: .8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chip-menu-group {
  display: flex;
  flex-direction: column;
  padding: .3rem 0;
}

.chip-menu-group + .chip-menu-group {
  border-top: 1px solid var(--hairline, #EDEDEB);
  margin-top: .3rem;
}

/* Fix round 2: the "verify your email" nudge row (.chip-verify-nudge) is
   gone from this menu -- that action moved to the new /account page (see
   account.html) -- so its selector is dropped here too, leaving just the
   two row kinds the menu still has (the four nav links, the sign-out
   button). */
.chip-menu .chip-menu-link,
.chip-menu button {
  color: var(--ink, #18181B);
  padding: .55rem .6rem;
  display: block;
  width: 100%;
  text-align: left;
  text-decoration: none;
  border-radius: 6px;
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chip-menu .chip-menu-link:hover,
.chip-menu button:hover {
  background: var(--hairline, #EDEDEB);
}

/* Language/Theme submenu rows (design directive 2026-08-20): the two rows
   stopped click-to-cycling and now open an inline OPTIONS MENU instead --
   `.chip-menu-item` wraps a toggle row (`.chip-menu-row-toggle`, styled by
   the `.chip-menu button` rule above -- this just adds the disclosure
   chevron) and an indented `.chip-menu-options` group, shown/hidden via
   the `hidden` attribute alone (one DOM primitive, matching how
   `.lang-dropdown-menu[hidden]` already does it above in this same file's
   sibling component). Each `.chip-menu-option` reuses that dropdown's own
   label + fading-in-checkmark idiom -- `aria-selected="true"` on the
   active option is the single source of truth the checkmark's opacity
   keys off. */
.chip-menu .chip-menu-row-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
}

.chip-menu-row-toggle::after {
  content: "";
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-right: 1.5px solid var(--secondary, #52525B);
  border-bottom: 1.5px solid var(--secondary, #52525B);
  transform: rotate(45deg);
  transition: transform .15s ease;
}

.chip-menu-row-toggle[aria-expanded="true"]::after {
  transform: rotate(-135deg);
}

.chip-menu-options {
  display: flex;
  flex-direction: column;
  padding: .15rem 0 .3rem .75rem;
}

.chip-menu-options[hidden] {
  display: none;
}

.chip-menu .chip-menu-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  padding: .45rem .6rem;
  font-size: .8rem;
}

.chip-menu-option-check {
  opacity: 0;
  flex-shrink: 0;
}

.chip-menu-option[aria-selected="true"] .chip-menu-option-check {
  opacity: 1;
}
