/* Self-hosted type. Chatty's direction: an editorial athletic brand, not a dark SaaS
   dashboard - a bold display face for headings and stats, a cleaner face for UI.
   Self-hosted is what makes this compatible with the strict 'self' CSP: the files are
   ours, nothing is fetched from a CDN at runtime. Both SIL OFL 1.1, latin subset,
   120 KB total. Licences live beside the files in static/fonts/. */
@font-face{
  font-family:'Archivo';
  src:url('/static/fonts/archivo-latin.woff2') format('woff2');
  font-weight:400 800;          /* variable */
  font-stretch:100% 125%;       /* the "Expanded" look comes from this axis */
  font-style:normal;
  font-display:swap;            /* text renders immediately in the fallback, then swaps */
}
@font-face{
  font-family:'Instrument Sans';
  src:url('/static/fonts/instrument-sans-latin.woff2') format('woff2');
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  /* Palette adopted from the GPT-arena (GLM) design pass, 2026-08-17.
     Every previous token name is kept as an ALIAS below, so the rest of this
     stylesheet - and every template - keeps working unchanged. */

  /* surfaces: a stop deeper, for contrast on OLED phones */
  --bg:#0d1015; --panel:#141922; --panel-2:#1b2230; --line:#26303f; --bg0:#07080b;

  /* ink */
  --ink:#f2f6fb; --ink-dim:#93a1b4; --ink-faint:#5c6a7d;

  /* signal. Lime is EARNED, not ambient: achievement and primary action only,
     so that when it appears it actually lands. */
  --lime:#c8ff4d; --lime-deep:#8fd400;
  --cyan:#54e5ff;      /* exceeding */
  --violet:#a78bfa;    /* personal best ONLY */
  --amber:#ffb454;     /* streak / warning */

  /* radii: three, used with intent */
  --r-sm:12px; --r-md:18px; --r-lg:28px;

  /* motion: one easing family */
  --out:cubic-bezier(.16,1,.3,1);
  --spring:cubic-bezier(.34,1.56,.64,1);
  --io:cubic-bezier(.65,0,.35,1);

  /* type */
  --display:'Archivo', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --ui:'Instrument Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* aliases - the old names, pointed at the new values */
  --accent:var(--lime); --accent-2:var(--cyan);
  --on:var(--lime); --exceed:var(--cyan); --miss:#ff6b7a; --none:#64748b;
  --warn:var(--amber);
  --radius:var(--r-md);
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font:16px/1.5 var(--ui);
  -webkit-text-size-adjust:100%;
}
a{color:var(--accent-2); text-decoration:none}
a:hover{text-decoration:underline}

/* ---------------------------------------------------------------- chrome */
.topbar{
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  padding:10px 16px; background:#12161c; border-bottom:1px solid var(--line);
  position:sticky; top:0; z-index:20;
}
.brand{font-weight:800; letter-spacing:.04em; color:var(--accent); font-size:19px;
  font-stretch:120%}
.brand span{color:var(--ink-dim)}
.topbar nav{display:flex; gap:14px; flex-wrap:wrap; flex:1}
.topbar nav a{color:var(--ink-dim); font-size:14px; font-weight:600}
.topbar nav a:hover{color:var(--ink); text-decoration:none}
main{max-width:1080px; margin:0 auto; padding:18px 16px 80px}
footer{
  max-width:1080px; margin:0 auto; padding:20px 16px 40px; display:flex;
  justify-content:space-between; color:var(--ink-dim); font-size:12px;
}
h1,h2,h3,.big,.celebrate-num,.celebrate-title,.eyebrow,.ringnum,.brand{
  font-family:var(--display); font-stretch:112%;
}
h1{font-size:23px; margin:6px 0 14px; letter-spacing:-.025em; font-weight:800}
h2{font-size:18px; margin:26px 0 10px; font-weight:800; letter-spacing:-.015em}
h3{font-size:15px; margin:0 0 8px; font-weight:800}
p.sub{color:var(--ink-dim); margin:-6px 0 16px; font-size:14px}

.flash{
  background:#14321f; border:1px solid #256b3f; color:#c7f5d9;
  padding:10px 14px; border-radius:10px; margin-bottom:16px; font-size:14px;
}

/* ---------------------------------------------------------------- cards */
.card{
  background:var(--panel); border:1px solid var(--line); border-radius:var(--radius);
  padding:16px; margin-bottom:14px;
}
.card.tight{padding:12px 14px}
.grid{display:grid; gap:14px}
@media(min-width:720px){ .grid.two{grid-template-columns:1fr 1fr} .grid.three{grid-template-columns:repeat(3,1fr)} }
.row{display:flex; gap:10px; flex-wrap:wrap; align-items:center}
.row.between{justify-content:space-between}
.muted{color:var(--ink-dim)}
.small{font-size:13px}
.big{font-size:30px; font-weight:800; line-height:1.1; letter-spacing:-.045em;
  font-variant-numeric:tabular-nums; font-stretch:118%}
/* Eyebrow: small, wide-tracked, faint. Replaces "bold grey label" and reads as a system. */
.eyebrow{font-size:12px; font-weight:800; letter-spacing:.28em; text-transform:uppercase;
  color:var(--ink-faint)}

/* ---------------------------------------------------------------- status */
.chip{
  display:inline-block; padding:3px 10px; border-radius:999px; font-size:12px;
  font-weight:700; letter-spacing:.02em; border:1px solid transparent; white-space:nowrap;
}
.chip.missed{background:rgba(255,107,122,.14); color:var(--miss); border-color:rgba(255,107,122,.35)}
.chip.on_target{background:rgba(200,255,77,.14); color:var(--on); border-color:rgba(200,255,77,.35)}
.chip.exceeded{background:rgba(84,229,255,.14); color:var(--exceed); border-color:rgba(84,229,255,.35)}
.chip.no_data{background:rgba(100,116,139,.16); color:var(--none); border-color:rgba(100,116,139,.35)}
.bar{height:8px; background:#232d3b; border-radius:999px; overflow:hidden; margin-top:8px}
.bar > i{display:block; height:100%; border-radius:999px; background:var(--on)}
.bar > i.missed{background:var(--miss)} .bar > i.exceeded{background:var(--exceed)}
.bar > i.no_data{background:var(--none)}

/* ---------------------------------------------------------------- forms */
label{display:block; font-size:13px; color:var(--ink-dim); margin:10px 0 4px; font-weight:600}
input[type=text],input[type=email],input[type=password],input[type=number],input[type=date],
select,textarea{
  width:100%; padding:11px 12px; background:var(--panel-2); color:var(--ink);
  border:1px solid var(--line); border-radius:10px; font-size:16px; font-family:inherit;
}
textarea{min-height:80px; resize:vertical}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent-2); outline-offset:1px}
.checkline{display:flex; align-items:center; gap:8px; margin:10px 0; font-size:14px}
.checkline input{width:20px; height:20px}
button,.btn{
  font-family:var(--ui);
  display:inline-block; padding:11px 16px; border-radius:10px; border:1px solid var(--line);
  background:linear-gradient(180deg,var(--lime),var(--lime-deep)); color:#0d1015;
  font-weight:800; font-size:15px; cursor:pointer;
  font-family:inherit;
}
button.ghost,.btn.ghost{background:transparent; color:var(--ink); border-color:var(--line)}
button.danger{background:transparent; color:var(--miss); border-color:rgba(248,113,113,.4)}
button.link{background:none; border:none; color:var(--ink-dim); padding:6px; font-weight:600}
button.small,.btn.small{padding:7px 11px; font-size:13px}
form.inline{display:inline}
.formgrid{display:grid; gap:10px}
@media(min-width:640px){ .formgrid.two{grid-template-columns:1fr 1fr} .formgrid.three{grid-template-columns:repeat(3,1fr)} }

/* ---------------------------------------------------------------- tables */
table{width:100%; border-collapse:collapse; font-size:14px}
th,td{padding:9px 8px; border-bottom:1px solid var(--line); text-align:left; vertical-align:top}
th{color:var(--ink-dim); font-size:12px; text-transform:uppercase; letter-spacing:.05em}
.scroll{overflow-x:auto; -webkit-overflow-scrolling:touch}

/* ---------------------------------------------------------------- session logger */
.block{border:1px solid var(--line); border-radius:var(--radius); margin-bottom:14px; overflow:hidden}
.block > header{
  background:var(--panel-2); padding:10px 14px; display:flex; justify-content:space-between;
  align-items:center; gap:10px; flex-wrap:wrap;
}
.block > header b{font-size:15px}
.exercise{padding:12px 14px; border-top:1px solid var(--line)}
.exercise:first-of-type{border-top:none}
.exercise .target{color:var(--ink-dim); font-size:13px; margin-top:2px}
.setrow{
  display:flex; gap:8px; align-items:flex-end; padding:8px 0; flex-wrap:wrap;
  border-top:1px dashed rgba(42,53,67,.7);
}
.setrow .n{width:44px; color:var(--ink-dim); font-weight:700; font-size:13px; padding-bottom:11px}
.setrow .f{flex:1 1 90px; min-width:80px}
.setrow label{margin:0 0 3px}
.setrow button{padding:11px 14px}
.done{border-left:3px solid var(--on)}
.pill{background:var(--panel-2); border:1px solid var(--line); border-radius:999px;
  padding:4px 10px; font-size:12px; color:var(--ink-dim)}
.pw{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:18px; letter-spacing:.04em;
  background:#0b0f14; border:1px dashed var(--warn); color:var(--warn);
  padding:10px 14px; border-radius:10px; display:inline-block; user-select:all;
}
.login-wrap{max-width:380px; margin:8vh auto}
.login-wrap .card{padding:22px}

/* "View as client" - must never be mistaken for the real client session */
.previewbar{
  display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap;
  background:repeating-linear-gradient(45deg,#2a2410,#2a2410 10px,#241f0e 10px,#241f0e 20px);
  border:1px solid var(--warn); border-radius:var(--radius);
  padding:12px 14px; margin-bottom:16px;
}
.previewbar b{color:var(--warn); display:block}
.previewbar .small{color:var(--ink-dim)}
/* The banner's stripes wash out the default green button - give its actions their own
   solid, high-contrast treatment so "Back to admin" is always readable. */
.previewbar .btn{background:var(--warn); color:#231a00; border-color:#a97c05}
.previewbar .btn.ghost{background:#0f1319; color:var(--ink); border-color:#6b5307}

/* ---------------------------------------------------------------- celebration */
.celebrate-canvas{position:fixed; inset:0; pointer-events:none; z-index:60}
.celebrate{
  text-align:center; padding:26px 18px 22px; margin-bottom:18px; border-radius:var(--radius);
  border:1px solid var(--line); position:relative; overflow:hidden;
  background:radial-gradient(120% 90% at 50% 0%, rgba(56,189,248,.16), transparent 60%),
             var(--panel);
  animation:rise .5s cubic-bezier(.2,.8,.2,1) both;
}
.celebrate-mark{
  font-size:40px; line-height:1; color:var(--accent);
  animation:pop .55s cubic-bezier(.2,1.3,.4,1) both;
}
.celebrate-title{margin:10px 0 2px; font-size:20px}
.celebrate-num{font-size:58px; font-weight:800; letter-spacing:-.045em;
  font-variant-numeric:tabular-nums; font-stretch:118%}
@keyframes rise{from{opacity:0; transform:translateY(14px)}to{opacity:1; transform:none}}
@keyframes pop{0%{transform:scale(.4); opacity:0}70%{transform:scale(1.15)}100%{transform:scale(1); opacity:1}}
@keyframes popin{from{opacity:0; transform:translateY(8px) scale(.94)}to{opacity:1; transform:none}}

.award{
  display:flex; flex-direction:column; gap:2px; padding:10px 14px; border-radius:12px;
  background:linear-gradient(150deg,#1d2735,#161d27); border:1px solid #33465c; min-width:140px;
}
.award b{color:var(--accent)}
.award-pop{animation:popin .45s cubic-bezier(.2,1.2,.4,1) both}
.streakcard{background:linear-gradient(150deg,#221d12,var(--panel)); border-color:#4a3a1a}
.streakcard .big{color:var(--amber)}
.award b{color:var(--lime)}
.award.pb{border-color:#4b3f7a}
.award.pb b{color:var(--violet)}
.spark{width:100%; height:44px; margin-top:8px; color:var(--accent-2); display:block}

/* ---------------------------------------------------------------- calendar */
.weekgrid{display:grid; gap:10px; grid-template-columns:1fr}
@media(min-width:860px){ .weekgrid{grid-template-columns:repeat(7,1fr)} }
.daycol{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:10px}
.daycol.istoday{border-color:var(--accent)}
.daycol > header{display:flex; justify-content:space-between; align-items:baseline; margin-bottom:8px}
.slot{
  background:var(--panel-2); border:1px solid var(--line); border-left:3px solid var(--accent-2);
  border-radius:10px; padding:8px 10px; margin-bottom:8px; font-size:13px;
}
.slot.status-done{border-left-color:var(--on)}
.slot.status-cancelled{border-left-color:var(--none); opacity:.6}
.slot.status-no_show{border-left-color:var(--miss)}

/* ---------------------------------------------------------------- share card */
.sharecanvas{width:100%; max-width:360px; height:auto; border-radius:12px; border:1px solid var(--line); display:block}

/* Every effect needs a kill switch. */
@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important; transition-duration:.01ms !important}
}

/* Streak ring: one animatable number (stroke-dashoffset), effectively free on a phone.
   Amber says "streak" without borrowing a flame emoji's visual language. */
.ringcard{text-align:center}
.ringwrap{position:relative; width:150px; margin:10px auto 6px}
.ring{width:150px; height:150px; transform:rotate(-90deg); display:block}
.ring circle{fill:none; stroke-width:8; stroke-linecap:round}
.ring-track{stroke:#2a2415}
.ring-value{stroke:var(--amber); filter:drop-shadow(0 0 6px rgba(255,180,84,.45))}
.ringnum{
  position:absolute; inset:0; display:flex; flex-direction:column; align-items:center;
  justify-content:center; font-size:40px; font-weight:800; letter-spacing:-.04em;
  color:var(--amber); font-variant-numeric:tabular-nums;
}
.ringnum small{font-size:12px; font-weight:700; letter-spacing:.22em; text-transform:uppercase;
  color:var(--ink-faint)}
.pbmoment{background:radial-gradient(120% 90% at 50% 0%, rgba(167,139,250,.20), transparent 60%),
  var(--panel); border-color:#4b3f7a}
.pbmoment .celebrate-num{color:var(--violet)}
