/* Habits. Light theme from the approved mockup (2026-11-03). Spacing on a 4/8 px ladder,
   one radius scale (12 / 16 / 20 / 24 / pill), 16 px body and input text. No inline styles:
   the CSP refuses them, so colours come from .c-<name> classes and sizes from JS (el.style). */
:root{
  --bg:#f5f5f6; --card:#fff; --ink:#18181b; --muted:#6b6b74; --line:#e4e4e7;
  --accent:#4f46e5; --r:20px; --r-sm:12px; --danger:#dc2626;
  --c:#6366f1; --tint:#6366f114; --tint2:#6366f126; --empty:#6366f11f;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--ink);font-size:16px;line-height:1.4}
.app{max-width:480px;margin:0 auto;padding:16px 16px calc(112px + env(safe-area-inset-bottom))}
.app.narrow{max-width:420px;padding-top:48px}
button{font:inherit;color:inherit;cursor:pointer}
a{color:var(--accent)}
h1,h2{margin:0}
.grow{flex:1;min-width:0}
.center{text-align:center}
.small{font-size:14px}
.muted{color:var(--muted)}
.mono{font-family:ui-monospace,"SF Mono",Consolas,monospace;letter-spacing:.04em}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
[hidden]{display:none!important}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.top{display:flex;align-items:center;gap:8px;margin-bottom:16px}
.round{width:48px;height:48px;border-radius:50%;border:0;background:#e9e9ec;display:grid;place-items:center;font-size:20px;color:inherit;text-decoration:none;flex:none}
.round:hover{background:#dfdfe3}
.round[disabled]{opacity:.4;cursor:default}
.round.primary{background:var(--accent);color:#fff;font-size:26px;box-shadow:0 6px 18px rgb(79 70 229 / .3)}
.round.primary:hover{filter:brightness(1.08)}
.title{font-size:24px;font-weight:700;margin:0}
.h2{font-size:18px;margin:0 0 8px}
.banner{font-size:14px;color:var(--muted);text-align:center;margin:-4px 0 12px;min-height:20px}
.banner.warn{color:#b45309}
.loading{padding:48px 0}

/* habit cards */
.card{background:var(--card);border-radius:var(--r);padding:16px;margin-bottom:16px;box-shadow:0 1px 3px rgb(24 24 27 / .06);
  background-image:linear-gradient(180deg, var(--tint) 0%, transparent 60%)}
.card.flush{padding:0;overflow:hidden}
.card-head{display:flex;align-items:center;gap:12px;margin-bottom:12px}
.icon{width:52px;height:52px;border-radius:16px;display:grid;place-items:center;font-size:26px;background:var(--tint2);flex:none;border:0;text-decoration:none;color:inherit}
.hname{flex:1;font-weight:600;font-size:18px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:12px 0;color:inherit;text-decoration:none}
.hname .goal{font-size:14px;font-weight:400;color:var(--muted)}
.check{width:52px;height:52px;border-radius:16px;border:1.5px solid var(--line);background:#f4f4f5;display:grid;place-items:center;color:#a1a1aa;font-size:24px;flex:none;transition:background .15s, color .15s, transform .1s}
.check:active{transform:scale(.94)}
.check.on{background:var(--c);border-color:var(--c);color:#fff;box-shadow:0 4px 12px var(--tint2)}
.dots{display:grid;grid-auto-flow:column;grid-template-rows:repeat(7,1fr);gap:3px}
/* Home cards: the grid alone scrolls sideways. 26 week columns fill the visible width (cqw = the
   scroller), older weeks wait to the left; no scroll bar, and the page never widens. */
.dotscroll{container-type:inline-size;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;touch-action:pan-x pan-y;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.dotscroll::-webkit-scrollbar{display:none}
.dots.wide{width:max-content;grid-auto-columns:calc((100cqw - 75px) / 26)}
.year.wide{width:max-content;grid-auto-columns:calc((100cqw - 75px) / 26)}
.dot{aspect-ratio:1;border-radius:3px;background:var(--empty);position:relative}
.dot.on{background:var(--c)}
.dot.future{background:transparent}
.dot.later{background:var(--empty);opacity:.45}
.dot.nt::after{content:'';position:absolute;inset:28%;border-radius:50%;background:var(--c)}
.dot.on.nt::after{background:#fff}
.day,.tcell{position:relative;overflow:hidden}
.nt-c::after{content:'';position:absolute;top:0;right:0;width:14px;height:14px;background:var(--c);clip-path:polygon(0 0,100% 0,100% 100%)}
.on.nt-c::after{background:rgb(255 255 255 / .92)}
.empty-state{text-align:center;padding:32px 16px}
.empty-state p{margin:8px 0 16px}

/* 5-day table */
.table{background:var(--card);border-radius:var(--r);overflow:hidden;box-shadow:0 1px 3px rgb(24 24 27 / .06)}
.trow{display:grid;grid-template-columns:minmax(0,1fr) repeat(5,40px);gap:4px;align-items:center;padding:10px 12px;border-top:1px solid var(--line)}
.trow:first-child{border-top:0}
.trow .small{font-size:12px;text-align:center;line-height:1.3}
.tcell{height:44px;border-radius:12px;border:0;background:var(--empty)}
.tcell.on{background:var(--c)}
.tname{display:flex;align-items:center;gap:10px;min-width:0;color:inherit;text-decoration:none;min-height:44px}
.tname{gap:8px}
.tname .icon{width:32px;height:32px;font-size:18px;border-radius:10px}
.tname .nm{font-size:14px;line-height:1.25;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow-wrap:break-word}
@media (max-width:380px){.trow{grid-template-columns:minmax(0,1fr) repeat(5,36px);padding:10px 8px}.tcell{height:40px}.tname{gap:6px}.tname .icon{width:28px;height:28px;font-size:16px;border-radius:9px}}

/* month compact */
.mgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.mcard{background:var(--card);border-radius:16px;padding:8px;box-shadow:0 1px 3px rgb(24 24 27 / .06)}
.mcard .row{display:flex;align-items:center;gap:6px;margin-bottom:8px;font-size:13px}
.mcard .mini{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;font-size:18px;background:var(--empty);border:0;flex:none}
.mcard .mini.on{background:var(--c)}
.mcard a{color:inherit;text-decoration:none;min-width:0}
.mcard b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mdots{display:grid;grid-template-columns:repeat(7,1fr);gap:3px}

/* view switcher */
.dock{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(16px + env(safe-area-inset-bottom));background:#fff;border-radius:999px;padding:6px;display:flex;gap:4px;box-shadow:0 8px 28px rgb(24 24 27 / .14);z-index:5}
.dock button{width:72px;height:48px;border-radius:999px;border:0;background:none;font-size:14px;color:var(--muted)}
.dock button[aria-pressed=true]{background:#ececef;color:var(--ink);font-weight:600}

/* habit page */
.hero{display:flex;gap:16px;align-items:center;margin:8px 0 16px}
.hero .icon{width:72px;height:72px;font-size:36px;border-radius:20px}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin:16px 0}
.chip{border-radius:999px;padding:8px 14px;background:var(--tint2);color:var(--ink);font-weight:600;font-size:14px;white-space:nowrap}
.year{display:grid;grid-auto-flow:column;grid-template-rows:14px repeat(7,auto);grid-auto-columns:minmax(0,1fr);gap:3px;width:100%}
.year .lbl{font-size:10px;color:var(--muted);white-space:nowrap;overflow:visible}
.cal{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;text-align:center}
.cal .wd{font-size:12px;color:var(--muted);padding:4px 0}
.day{height:52px;border-radius:14px;border:0;background:transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:16px}
.day.in{background:var(--tint2)}
.day.on{background:var(--c);color:#fff;font-weight:600}
.day.today{outline:2px solid var(--c);outline-offset:-2px}
.day.out{color:#a1a1aa}
.day.out.on{background:color-mix(in srgb, var(--c) 40%, #fff);color:var(--ink);font-weight:600}
.day.future{color:#c4c4c9;cursor:default}
.calnav{display:flex;align-items:center;gap:8px;margin-top:12px}
.calnav .label{flex:1;text-align:center;font-weight:600}
.hint{text-align:center;font-size:14px;color:var(--muted);margin:12px 0 0}
.card-title{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.card-title h2{flex:1;font-size:18px}
.nlink{display:block;width:100%;text-align:left;background:none;border:0;padding:12px 0;border-top:1px solid var(--line);white-space:pre-wrap;overflow-wrap:anywhere}
.nlink:first-of-type{border-top:0}
.nlink .mono{font-size:12px;display:block;margin-bottom:2px}
.addnote{height:44px;padding:0 16px;border-radius:999px;border:0;background:var(--tint2);color:var(--ink);font-weight:600}

/* stats */
.hchips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}
.hchip{flex:none;height:44px;min-width:44px;padding:0 14px;border-radius:999px;border:0;background:#e9e9ec;font-size:18px}
.hchip.all{font-size:15px}
.hchip[aria-pressed=true]{background:var(--ink);color:#fff}
.tiles{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:12px 0}
.tile{background:var(--card);border-radius:var(--r);padding:16px;box-shadow:0 1px 3px rgb(24 24 27 / .06)}
.tile b{display:block;font-size:36px;font-variant-numeric:tabular-nums;line-height:1.1;white-space:nowrap}
.bars{display:flex;align-items:flex-end;gap:6px;height:140px;margin-top:12px}
.bar{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;height:100%;justify-content:flex-end;min-width:0}
.bar i{display:block;width:100%;border-radius:6px 6px 2px 2px;background:var(--c);opacity:.8;min-height:2px}
.bar span,.bar em{font-size:11px;color:var(--muted);font-style:normal;font-variant-numeric:tabular-nums}

/* edit list */
.rows{list-style:none;margin:0;padding:0}
.rows li{border-top:1px solid var(--line)}
.rows li:first-child{border-top:0}
.rows a,.rows .row{display:flex;align-items:center;gap:12px;padding:12px 16px;min-height:56px;color:inherit;text-decoration:none}
.rows b{display:block}
.rows .icon{width:40px;height:40px;font-size:20px;border-radius:12px}
.rows .nm{display:block;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mini-btn{width:44px;height:44px;border-radius:12px;border:0;background:#ececef;font-size:18px;flex:none}
.mini-btn[disabled]{opacity:.35;cursor:default}
.sec-title{font-size:14px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin:24px 4px 8px}

/* sheets */
dialog{border:0;border-radius:24px 24px 0 0;padding:20px 20px calc(20px + env(safe-area-inset-bottom));width:100%;max-width:480px;margin:auto auto 0;max-height:90vh;overflow:auto;color:var(--ink)}
dialog:not([open]){display:none}
dialog::backdrop{background:rgb(24 24 27 / .35)}
.sheet-head{display:flex;align-items:center;gap:12px;margin-bottom:16px}
.sheet-head h2{flex:1;margin:0;font-size:20px;text-align:center}
.sheet-spacer{width:48px;flex:none}
.note-habit{display:flex;align-items:center;gap:12px}
.f{display:block;font-size:13px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin:16px 0 6px}
.bare{border:0;padding:0;margin:0;min-width:0}
.bare{margin-top:16px}
.bare legend{padding:0}
.bare legend.f{margin-top:0}
input[type=text],input[type=password],input[type=number],textarea{width:100%;font:inherit;font-size:16px;padding:12px 14px;border:1.5px solid var(--line);border-radius:var(--r-sm);background:#fff;color:var(--ink)}
input:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:1px;border-color:transparent}
input[aria-invalid=true]{border-color:var(--danger)}
.emoji-in{width:96px!important;text-align:center;font-size:24px!important}
textarea{min-height:112px;resize:vertical}
.err{color:var(--danger);font-size:14px;min-height:20px;margin:4px 0 0}
.err-box{color:var(--danger);background:#fef2f2;border-radius:var(--r-sm);padding:12px 14px;margin:12px 0}
.hint{text-align:left;margin:4px 0 0}
.fld .hint{font-size:14px}
.swatches{display:grid;grid-template-columns:repeat(7,1fr);gap:8px}
.swatches label{aspect-ratio:1;border-radius:12px;display:block;cursor:pointer;position:relative;min-height:40px}
.swatches input{position:absolute;opacity:0;inset:0}
.swatches span{display:block;width:100%;height:100%;border-radius:12px;background:var(--c)}
.swatches input:checked+span{outline:3px solid var(--ink);outline-offset:2px}
.swatches input:focus-visible+span{outline:3px solid var(--accent);outline-offset:2px}
.seg{display:grid;grid-template-columns:1fr 1fr;background:#ececef;border-radius:14px;padding:4px}
.seg button{border:0;background:none;height:44px;border-radius:10px;color:var(--muted)}
.seg button[aria-pressed=true]{background:#fff;color:var(--ink);font-weight:600;box-shadow:0 1px 3px rgb(0 0 0 / .08)}
.stepper{display:flex;align-items:center;gap:12px;margin-top:12px}
.stepper button{width:44px;height:44px;border-radius:12px;border:0;background:#ececef;font-size:20px}
.stepper b{min-width:24px;text-align:center;font-variant-numeric:tabular-nums}
.btn{display:block;width:100%;height:52px;border-radius:16px;border:0;background:var(--accent);color:#fff;font-weight:600;margin-top:20px;text-align:center;line-height:52px;text-decoration:none}
.btn:hover{filter:brightness(1.08)}
.btn[aria-busy=true]{opacity:.7}
.btn-quiet{background:#ececef;color:var(--ink)}
.ghost{height:44px;padding:0 16px;border-radius:999px;border:1.5px solid var(--line);background:#fff}
.ghost[disabled]{opacity:.4;cursor:default}
.ghost.wide{display:block;width:100%;margin-top:12px;height:48px}
.ghost.danger{color:var(--danger)}
.linkbtn{background:none;border:0;color:var(--accent);text-decoration:underline;padding:12px 4px;min-height:44px}
.toast{position:fixed;left:50%;top:calc(16px + env(safe-area-inset-top));transform:translateX(-50%);background:var(--ink);color:#fff;padding:10px 16px;border-radius:999px;font-size:14px;opacity:0;transition:opacity .2s;pointer-events:none;z-index:10;max-width:calc(100% - 32px)}
.toast.show{opacity:1}
[data-note]{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:transform .45s ease-out}
[data-note].holding{transform:scale(.9)}

/* server pages */
.form-card .title{margin-bottom:8px}
.flashes{list-style:none;margin:0 0 16px;padding:0}
.flash{background:#ecfdf5;color:#065f46;border-radius:var(--r-sm);padding:12px 14px;margin-bottom:8px}
.flash-err{background:#fef2f2;color:var(--danger)}
.checkrow{display:flex;gap:12px;align-items:center;min-height:44px;margin-top:12px}
.checkrow input{width:24px;height:24px}
.logout-form{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:16px 0}
.tag{font-size:12px;background:#ececef;border-radius:999px;padding:2px 8px;white-space:nowrap}
.copy-row{display:flex;gap:8px;align-items:center}
.copy-row input{font-family:ui-monospace,Consolas,monospace;font-size:14px!important}
.lock-panel{text-align:center}
.pin-boxes{position:relative;display:flex;justify-content:center;gap:12px;margin:16px 0 8px}
.pin-input{position:absolute;inset:0;opacity:0;width:100%;height:100%}
.pin-box{width:16px;height:16px;border-radius:50%;border:2px solid var(--muted)}
.pin-box.is-on{background:var(--ink);border-color:var(--ink)}
.pin-msg{min-height:20px;font-size:14px;color:var(--muted);margin:8px 0}
.pin-msg.is-err{color:var(--danger)}
.pin-pad{display:grid;grid-template-columns:repeat(3,72px);gap:12px;justify-content:center;margin:8px 0}
.pin-key{width:72px;height:72px;border-radius:50%;border:0;background:#ececef;font-size:24px}
.pin-key:active{background:#dfdfe3}
.lock-form.is-pad .lock-send{display:none}
.lock-form.is-wrong .pin-boxes{animation:shake .35s}
@keyframes shake{25%{transform:translateX(-8px)}75%{transform:translateX(8px)}}
html.pin-hold body{visibility:hidden}

@media (prefers-reduced-motion: reduce){*{transition:none!important;animation:none!important}}

/* colours: one class per name in habits.COLORS; tests/test_pages.py checks they match */
.c-red{--c:#ef4444;--tint:#ef444414;--tint2:#ef444426;--empty:#ef44441f}
.c-orange{--c:#f97316;--tint:#f9731614;--tint2:#f9731626;--empty:#f973161f}
.c-amber{--c:#f59e0b;--tint:#f59e0b14;--tint2:#f59e0b26;--empty:#f59e0b1f}
.c-lime{--c:#84cc16;--tint:#84cc1614;--tint2:#84cc1626;--empty:#84cc161f}
.c-green{--c:#22c55e;--tint:#22c55e14;--tint2:#22c55e26;--empty:#22c55e1f}
.c-emerald{--c:#10b981;--tint:#10b98114;--tint2:#10b98126;--empty:#10b9811f}
.c-teal{--c:#14b8a6;--tint:#14b8a614;--tint2:#14b8a626;--empty:#14b8a61f}
.c-cyan{--c:#06b6d4;--tint:#06b6d414;--tint2:#06b6d426;--empty:#06b6d41f}
.c-sky{--c:#0ea5e9;--tint:#0ea5e914;--tint2:#0ea5e926;--empty:#0ea5e91f}
.c-blue{--c:#3b82f6;--tint:#3b82f614;--tint2:#3b82f626;--empty:#3b82f61f}
.c-indigo{--c:#6366f1;--tint:#6366f114;--tint2:#6366f126;--empty:#6366f11f}
.c-violet{--c:#8b5cf6;--tint:#8b5cf614;--tint2:#8b5cf626;--empty:#8b5cf61f}
.c-purple{--c:#a855f7;--tint:#a855f714;--tint2:#a855f726;--empty:#a855f71f}
.c-fuchsia{--c:#d946ef;--tint:#d946ef14;--tint2:#d946ef26;--empty:#d946ef1f}
.c-pink{--c:#ec4899;--tint:#ec489914;--tint2:#ec489926;--empty:#ec48991f}
.c-rose{--c:#f43f5e;--tint:#f43f5e14;--tint2:#f43f5e26;--empty:#f43f5e1f}
.c-slate{--c:#64748b;--tint:#64748b14;--tint2:#64748b26;--empty:#64748b1f}
.c-stone{--c:#78716c;--tint:#78716c14;--tint2:#78716c26;--empty:#78716c1f}
.c-all{--c:#6366f1;--empty:#6366f11f;--tint:#fff}
