/* ══════════════════════════════════════════════════════════════════════════
   COZY — login + profile                            created 2026-08-02
   ─────────────────────────────────────────────────────────────────────────
   The first ROOT pages on the design system. Until now `login.html` and
   `profile.html` loaded none of it — no `variables.css`, no cozy layer, just
   ~100 lines of inline CSS each with hardcoded hex (`#0a0a0a`, `#4f9cf9`,
   `#c9e8f7`) and their own private light-theme overrides. That was Finding 1
   of [[UI Design Audit 2026-08-01]]: three surfaces, three unrelated design
   systems, crossed by every new user in three clicks.

   Both pages' inline <style> blocks are DELETED, not overridden — otherwise
   the old hardcoded values keep winning on anything this file forgets.

   Lives in /assets/ rather than /app/src/css/ because these are root pages,
   not app views. They still pull tokens from `/app/src/css/variables.css`,
   which is a slightly odd path for a root page — the tokens' eventual home is
   /assets/, and moving them is part of the Home pass, when all three root
   pages need them at once.
   ══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after{ box-sizing:border-box; margin:0; padding:0; }

body{
  font-family:'Baloo 2','Baloo Thai 2',-apple-system,BlinkMacSystemFont,'Segoe UI','Sarabun',sans-serif;
  font-size:var(--cz-t-md); line-height:var(--cz-lh);
  color:var(--cz-ink);
  background-color:var(--cz-paper);
  background-image:radial-gradient(var(--cz-halftone) 1.3px, transparent 1.5px);
  background-size:15px 15px;
  min-height:100vh;
}

/* ── shared primitives ─────────────────────────────────────────────────────*/
.logo{
  font-size:var(--cz-t-2xl); font-weight:800; letter-spacing:-.01em;
  color:var(--cz-ink); line-height:var(--cz-lh-tight);
}
.logo span{ color:var(--cz-teal-d); }

label,
.field-label{
  display:block; font-size:var(--cz-t-sm); font-weight:800;
  color:var(--cz-ink); text-transform:none; letter-spacing:0;
}
.field{ display:flex; flex-direction:column; gap:var(--cz-s1); }
.field-hint{ font-size:var(--cz-t-xs); color:var(--cz-muted); line-height:var(--cz-lh); }

input{
  width:100%; font-family:inherit;
  font-size:var(--cz-t-md); line-height:var(--cz-lh);
  color:var(--cz-ink); background:var(--cz-panel-2);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-sm);
  padding:11px var(--cz-s3); outline:none;
  transition:border-color .12s, box-shadow .12s;
}
input::placeholder{ color:var(--cz-faint); }
input:focus{ outline:2px solid var(--cz-teal); outline-offset:1px; }
input:disabled{ opacity:.55; cursor:not-allowed; }

.prefix-wrap{
  display:flex; align-items:stretch; overflow:hidden;
  background:var(--cz-panel-2);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-sm);
}
.prefix-wrap:focus-within{ outline:2px solid var(--cz-teal); outline-offset:1px; }
/* --cz-muted on --cz-panel-2 measured 4.33:1 in LIGHT — just under AA, and
   only under it in one theme (dark was 6.7). The prefix still needs to read
   as secondary to the value the user types, so the de-emphasis moves from
   colour to WEIGHT: full-contrast ink, normal weight, against the input's
   own text. */
.prefix{
  display:flex; align-items:center; padding:0 var(--cz-s1) 0 var(--cz-s3);
  font-size:var(--cz-t-md); font-weight:400; color:var(--cz-ink);
  white-space:nowrap; flex-shrink:0;
}
.prefix-wrap input{ border:none; border-radius:0; padding-left:0; flex:1; background:transparent; }
.prefix-wrap input:focus{ outline:none; }

.hidden{ display:none !important; }

/* ── buttons ───────────────────────────────────────────────────────────────
   🔴 Order and specificity matter here, and the first version got it wrong.
   profile.html writes `class="btn btn-primary"`. With `.btn-primary` declared
   BEFORE `.btn`, the later `.btn` rule won the *background* (same specificity,
   later wins) while a `html:not(.light) .btn-primary` rule — higher
   specificity — kept winning the *colour*. Result in dark mode: `--cz-panel`
   text on `--cz-panel-2` background, measured **1.14:1**. Invisible in light
   mode, which is why one-theme checking would have shipped it.
   Fixed by declaring the variants AFTER `.btn` and qualifying them as
   `.btn.btn-primary` (0,2,0), so they win both properties outright, and by
   dropping the `:not()` override for an explicit per-theme colour. */
.btn{
  cursor:pointer; font-family:inherit;
  font-size:var(--cz-t-sm); font-weight:800; line-height:var(--cz-lh);
  padding:11px var(--cz-s4);
  color:var(--cz-ink); background:var(--cz-panel-2);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-sm);
  box-shadow:var(--cz-e1);
  transition:transform .1s, filter .12s;
}
.btn:disabled, button.primary:disabled{ opacity:.45; cursor:not-allowed; }

/* the deep step carries the contrasting label; a mid-tone never could */
button.primary,
.btn.btn-primary{
  width:100%; cursor:pointer; font-family:inherit;
  font-size:var(--cz-t-sm); font-weight:800; line-height:var(--cz-lh);
  padding:12px var(--cz-s4);
  background:var(--cz-teal-d); color:var(--cz-on-fill);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-sm);
  box-shadow:var(--cz-e1);
  transition:transform .1s, filter .12s;
}
/* light: --cz-teal-d is a DARK teal, so the label goes white.
   dark:  --cz-teal-d is a LIGHT teal, so --cz-on-fill (near-black) is right. */
html.light button.primary,
html.light .btn.btn-primary{ color:#FFFFFF; }
button.primary:hover:not(:disabled),
.btn.btn-primary:hover:not(:disabled){ filter:brightness(1.06); }
button.primary:active:not(:disabled),
.btn.btn-primary:active:not(:disabled){ transform:translateY(1px); }

.btn.btn-danger{ background:var(--cz-brick-t); color:var(--cz-ink); }
.btn.btn-danger:hover:not(:disabled){ filter:brightness(.96); }

.link-btn{
  align-self:center; width:auto; cursor:pointer; font-family:inherit;
  font-size:var(--cz-t-sm); font-weight:700;
  color:var(--cz-teal-d); background:none; border:none; padding:2px;
  text-decoration:underline; text-underline-offset:3px;
}
.link-btn:hover{ color:var(--cz-ink); }

/* status messages — tint + ink, never a saturated fill */
.err, .ok, .msg{
  display:none; font-size:var(--cz-t-sm); line-height:var(--cz-lh);
  text-align:center; padding:9px var(--cz-s3); border-radius:var(--cz-r-sm);
  border:1px solid var(--cz-line); color:var(--cz-ink);
}
.err, .msg.err{ background:var(--cz-brick-t); }
.ok,  .msg.ok { background:var(--cz-moss-t); }

/* ── login ─────────────────────────────────────────────────────────────────*/
body.cz-auth{ display:flex; align-items:center; justify-content:center; padding:var(--cz-s4); }

.card{
  width:380px; max-width:100%;
  display:flex; flex-direction:column; gap:var(--cz-s3);
  padding:var(--cz-s5) var(--cz-s5) var(--cz-s5);
  background:var(--cz-panel);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-lg);
  box-shadow:var(--cz-e2);
}
/* The mascot is the first thing a stranger sees of Strakus. It sits on a
   --cz-hero disc for the same reason the Dashboard's does: the Star Cutter is
   a CREAM body with an ink outline, so on light paper it would otherwise be
   cream-on-cream and vanish. */
.cz-auth-mascot{
  width:64px; height:64px; align-self:center; padding:6px; box-sizing:content-box;
  background:var(--cz-hero); border:1px solid var(--cz-line); border-radius:50%;
  filter:drop-shadow(0 4px 8px rgba(0,0,0,.18));
  animation:cz-auth-bob 4.5s ease-in-out infinite; transform-origin:center;
}
@keyframes cz-auth-bob{ 0%,100%{transform:translateY(0) rotate(-3deg)} 50%{transform:translateY(-5px) rotate(3deg)} }
@media (prefers-reduced-motion:reduce){ .cz-auth-mascot{ animation:none } }

.card .logo{ text-align:center; }
.tagline{
  font-size:var(--cz-t-md); color:var(--cz-muted); text-align:center;
  margin-top:calc(var(--cz-s1) * -1); line-height:var(--cz-lh);
}

.tabs{
  display:flex; gap:4px; padding:4px;
  background:var(--cz-panel-2);
  border:1px solid var(--cz-line); border-radius:var(--cz-pill);
}
.tab{
  flex:1; cursor:pointer; font-family:inherit;
  font-size:var(--cz-t-sm); font-weight:800; line-height:var(--cz-lh);
  padding:8px; color:var(--cz-muted);
  background:transparent; border:1px solid transparent; border-radius:var(--cz-pill);
  transition:background .12s, color .12s;
}
.tab:hover:not(.on){ color:var(--cz-ink); }
.tab.on{
  background:var(--cz-teal-t); color:var(--cz-ink);
  border-color:var(--cz-line); box-shadow:var(--cz-e1);
}

.top-float-bar{
  position:fixed; top:14px; right:16px; z-index:10;
  display:flex; align-items:center; gap:var(--cz-s1);
}
.btn-theme-float{
  cursor:pointer; font-family:inherit; font-size:var(--cz-t-md);
  padding:7px 11px; color:var(--cz-muted);
  background:var(--cz-panel); border:1px solid var(--cz-line);
  border-radius:var(--cz-r-sm); box-shadow:var(--cz-e1);
}
.btn-theme-float:hover{ color:var(--cz-ink); }
/* matches the app's topbar toggle exactly — same control, same treatment.
   Panel fill + ink outline + hard offset; NOT a colour fill (that collided
   with the avatar in the app and flattened across themes). */
.btn-lang-float{
  cursor:pointer; font-family:inherit;
  font-size:var(--cz-t-xs); font-weight:900; letter-spacing:.05em; line-height:1;
  padding:8px 13px; color:var(--cz-ink); background:var(--cz-panel);
  border:1.5px solid var(--cz-ink); border-radius:var(--cz-pill);
  box-shadow:2px 2px 0 var(--cz-ink);
  transition:transform .1s, box-shadow .1s, background .12s;
}
.btn-lang-float:hover{ background:var(--cz-panel-2); }
.btn-lang-float:active{ transform:translate(2px,2px); box-shadow:0 0 0 var(--cz-ink); }

/* ── profile ───────────────────────────────────────────────────────────────*/
.topbar{
  height:52px; display:flex; align-items:center; gap:var(--cz-s3);
  padding:0 var(--cz-s4);
  background:var(--cz-chrome); border-bottom:1px solid var(--cz-line);
}
.topbar .logo{ font-size:var(--cz-t-xl); }
.topbar-sep{ flex:1; }
.back-btn{
  display:inline-flex; align-items:center; gap:var(--cz-s1);
  font-size:var(--cz-t-sm); font-weight:800; text-decoration:none;
  padding:8px var(--cz-s3); color:var(--cz-ink);
  background:var(--cz-panel-2);
  border:1px solid var(--cz-line); border-radius:var(--cz-r-sm);
  box-shadow:var(--cz-e1);
}
.back-btn:hover{ background:var(--cz-panel); }

.page{
  max-width:640px; margin:var(--cz-s6) auto; padding:0 var(--cz-s4);
  display:flex; flex-direction:column; gap:var(--cz-s4);
}
.section{
  display:flex; flex-direction:column; gap:var(--cz-s3);
  padding:var(--cz-s4);
  background:var(--cz-panel);
  border:1px solid var(--cz-line); border-radius:var(--cz-r);
  box-shadow:var(--cz-e1);
}
/* a real section head, not an 11px grey legend — same shape as the app's
   .cz-sect: a title with a coloured rule threading a hue down the page */
.section-title{
  font-size:var(--cz-t-xl); font-weight:800; letter-spacing:-.02em;
  line-height:var(--cz-lh-tight); color:var(--cz-ink);
  text-transform:none; margin:0;
  padding-bottom:var(--cz-s1); border-bottom:3px solid var(--cz-sky);
}
.section:nth-of-type(2) .section-title{ border-bottom-color:var(--cz-ochre); }
.section:nth-of-type(3) .section-title{ border-bottom-color:var(--cz-olive); }
.section:nth-of-type(4) .section-title{ border-bottom-color:var(--cz-brick); }

.avatar-row{ display:flex; align-items:center; gap:var(--cz-s3); }
/* ochre, matching the app's topbar avatar — colour means "this is you", and
   it has to mean the same thing on both surfaces */
.avatar-lg{
  width:58px; height:58px; flex-shrink:0; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-size:var(--cz-t-xl); font-weight:900;
  color:var(--cz-on-fill); background:var(--cz-ochre);
  border:1px solid var(--cz-line); box-shadow:var(--cz-e1);
}
.avatar-info{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.avatar-name{ font-size:var(--cz-t-lg); font-weight:800; color:var(--cz-ink); }
.avatar-email{
  font-size:var(--cz-t-sm); color:var(--cz-muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.avatar-plan{
  display:inline-block; align-self:flex-start;
  font-size:var(--cz-t-xs); font-weight:800;
  padding:3px 11px; border-radius:var(--cz-pill);
  background:var(--cz-moss-t); color:var(--cz-ink);
  border:1px solid var(--cz-line);
}
/* account-status badge — profile.html used to set these as inline styles from
   JS (`#f87171` / `#4f9cf9`), which no stylesheet could reach. Tint + ink, so
   it reads in both themes and follows the tokens like everything else. */
#freeze-badge{
  display:inline-block; align-self:flex-start;
  font-size:var(--cz-t-xs); font-weight:800;
  padding:3px 11px; border-radius:var(--cz-pill);
  border:1px solid var(--cz-line); color:var(--cz-ink);
  background:var(--cz-panel-2);
}
#freeze-badge.is-active{ background:var(--cz-moss-t); }
#freeze-badge.is-frozen{ background:var(--cz-brick-t); }

.row{ display:flex; gap:var(--cz-s2); flex-wrap:wrap; align-items:center; }
.danger-note{ font-size:var(--cz-t-sm); color:var(--cz-muted); line-height:var(--cz-lh); }

@media (max-width:520px){
  .card{ width:100%; padding:var(--cz-s4); }
  .page{ margin:var(--cz-s4) auto; }
}
