/* ============================================================
   Perch — COMPONENTS
   Cut from hdw-ui's component set down to what one screen needs:
   a form field, a button, a status badge, a list row and the four
   screen states. No chips/segments (no filters or tabs on this
   screen), no cards/kanban/tables (everything is a list), no
   brand-pill or stage vocabulary (those are hdwOS's content
   pipeline, not Perch's).

   New here, per AGENTS.md "add the shapes Perch needs": the status
   dot, the section header + count, the money line and the big money
   figure, the fold, the morning line block, the rule row/add form
   and the rulebook box. Toast and the sheet live in app.css/data.css.
   ============================================================ */

/* ---- FORM (the sign-in gate and the settings add-rule form) ---- */
.field{margin-bottom:var(--s-4);}
.field:last-child{margin-bottom:0;}
.field label{display:block;font-size:var(--fs-caption);color:var(--fg2);margin-bottom:var(--s-1);}
.field input{width:100%;background:var(--bg);border:1px solid var(--border);color:var(--fg);font-family:var(--font-body);font-size:var(--fs-body);padding:10px 14px;outline:none;border-radius:var(--radius);transition:border-color var(--dur-fast) var(--ease);-webkit-appearance:none;}
.field input:focus{border-color:var(--border2);}
.field input::placeholder{color:var(--fg3);}
.field-hint{font-size:var(--fs-caption);color:var(--fg3);margin-top:var(--s-1);}
/* the phone-only 16px fix for this (iOS zooms the page around a smaller input on
   focus) is in responsive.css, which is where every @media in this kit lives */

/* ---- BUTTONS ---- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:var(--ctrl-h-lg);padding:0 var(--s-4);font-family:var(--font-body);font-size:var(--fs-body);font-weight:400;cursor:pointer;border:none;text-decoration:none;white-space:nowrap;line-height:1;background:var(--fg);color:var(--bg);border-radius:var(--radius);transition:background var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease),opacity var(--dur) var(--ease),transform .1s var(--ease);}
.btn:hover{opacity:.86;}
.btn:active{transform:scale(var(--press));}
.btn-ghost{background:transparent;color:var(--fg2);border:1px solid var(--border);}
.btn-ghost:hover{color:var(--fg);border-color:var(--border2);opacity:1;}
.btn-quiet{background:transparent;color:var(--fg2);border:1px solid transparent;}
.btn-quiet:hover{background:var(--bg2);color:var(--fg);opacity:1;}
.btn-accent{background:var(--orange);color:#fff;}
.btn-accent:hover{opacity:.88;}
.btn-danger{background:transparent;color:var(--no);border:1px solid color-mix(in srgb,var(--no) 35%,transparent);}
.btn-danger:hover{background:var(--no);border-color:var(--no);color:#fff;opacity:1;}
.btn-sm{min-height:var(--ctrl-h);padding:0 var(--s-3);font-size:var(--fs-small);}
.btn:disabled{opacity:.4;cursor:not-allowed;pointer-events:none;}
.btn.is-loading{color:transparent !important;pointer-events:none;position:relative;}
.btn.is-loading::after{content:"";position:absolute;top:50%;left:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border:2px solid var(--bg);border-top-color:transparent;border-radius:50%;animation:hdwSpin .6s linear infinite;}
.btn-ghost.is-loading::after,.btn-quiet.is-loading::after{border-color:var(--fg);border-top-color:transparent;}
@keyframes hdwSpin{to{transform:rotate(360deg);}}
.btn-icon{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;background:none;border:none;border-radius:50%;color:var(--fg2);cursor:pointer;transition:background var(--dur) var(--ease),color var(--dur) var(--ease),transform .1s var(--ease);}
.btn-icon svg{width:18px;height:18px;}
.btn-icon:hover{background:var(--bg3);color:var(--fg);}
.btn-icon:active{transform:scale(var(--press));}
.btn-icon.on{color:var(--orange);}
.btn-block{width:100%;}
/* the two icons this screen draws from its own sprite (eye / eye-off) */
svg.i{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;display:block;}
/* a control smaller than 40px still needs a 40px hit area — extend it with a
   pseudo-element rather than growing what you can see */
.hit-pad{position:relative;}
.hit-pad::before{content:"";position:absolute;top:50%;left:50%;width:var(--hit);height:var(--hit);transform:translate(-50%,-50%);}

/* ---- STATUS BADGE (grey chip that darkens for progress, plus done/late/now) ---- */
.badge{display:inline-flex;align-items:center;height:20px;padding:0 8px;font-size:var(--fs-caption);white-space:nowrap;border:1px solid transparent;border-radius:var(--r-sm);color:var(--t1-ink);background:var(--t1);}
.badge-grey{color:var(--t0-ink);background:var(--t0);border-color:var(--t0-ring);}
.badge-t1{color:var(--t1-ink);background:var(--t1);}
.badge-t2{color:var(--t2-ink);background:var(--t2);}
.badge-t3{color:var(--t3-ink);background:var(--t3);}
.badge-t4{color:var(--t4-ink);background:var(--t4);}
.badge-done{color:var(--ink-green);background:var(--yes-wash);}
.badge-late{color:var(--ink-red);background:var(--no-wash);}
.badge-now{color:var(--orange);background:color-mix(in srgb,var(--orange) 14%,transparent);}
/* "blocked" — an outline in the red token, never filled: it is a stop, not a status */
.badge-blocked{color:var(--no);background:transparent;border-color:color-mix(in srgb,var(--no) 45%,transparent);}
/* "parked" — set aside on purpose, so it reads quieter than even the idle grey */
.badge-parked{color:var(--fg3);background:transparent;}

/* ---- STATUS DOT (a robot's health: green / amber / red, or a hollow ring
   when it has never reported) ---- */
.dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto;display:inline-block;}
.dot-green{background:var(--yes);}
.dot-amber{background:var(--warn);}
.dot-red{background:var(--no);}
.dot-none{background:none;border:1.5px solid var(--t0-ring);}
/* someone is on the site right now. Orange, because on this screen orange
   already means now (the Now badge on a calendar row). The ring breathes out
   and fades, transform and opacity only. Reduced motion (base.css) stops the
   ring, which leaves the plain dot. */
.dot-live{background:var(--orange);position:relative;}
.dot-live::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--orange);animation:perchBreathe 2.4s var(--ease-out) infinite;}
@keyframes perchBreathe{from{transform:scale(1);opacity:.55;}to{transform:scale(2.8);opacity:0;}}

/* ---- SPARK — seven days in 16px, at the end of the pulse row. One series,
   so one colour for every bar, and today in orange, this screen's today
   colour. A day with no visits is a flat stub. A day before counting started
   is left empty, never drawn as a zero. The numbers live in the sheet the row
   opens, so this never has to carry one. ---- */
.spark{display:inline-flex;align-items:flex-end;gap:var(--s-0);height:16px;}
.spark i{display:block;width:4px;min-height:2px;background:var(--t3);border-radius:var(--r-xs) var(--r-xs) 0 0;}
.spark i.is-today{background:var(--orange);}
.spark i.is-zero{background:var(--border2);}
.spark i.is-off{visibility:hidden;}

/* ---- overdue text — a plain colour, not a chip, for a due/overdue date sitting
   inline in a line of prose ---- */
.overdue{color:var(--no);}

/* ---- LIST (a row of records — robots, needs you, today, money, drafts, saves, the log) ---- */
.list{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-box);overflow:hidden;}
.list-row{display:flex;align-items:center;gap:var(--s-3);width:100%;min-height:var(--hit);padding:var(--s-3) var(--s-4);border-bottom:1px solid var(--border);text-align:left;background:none;border-left:none;border-right:none;border-top:none;color:inherit;font:inherit;transition:background var(--dur-fast) var(--ease);}
.list-row:last-child{border-bottom:none;}
button.list-row{cursor:pointer;}
button.list-row:hover{background:var(--bg2);}
/* rows whose content wraps (a reason, an overdue line) align to the top, not the middle */
.list-row.wrap{align-items:flex-start;}
.list-row-lead{flex:0 0 auto;display:flex;align-items:center;padding-top:2px;}
/* Today's timed rows: a fixed-width leading time column so the titles beside
   them all start on the same line, the way an agenda reads */
.list-row-time{flex:0 0 46px;font-size:var(--fs-small);color:var(--fg3);padding-top:2px;}
.list-row-main{flex:1;min-width:0;}
.list-row-title{font-size:var(--fs-body);line-height:var(--lh-snug);color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.list-row-title.wrap{white-space:normal;}
.list-row-meta{font-size:var(--fs-small);color:var(--fg2);margin-top:2px;}
.list-row-sub{font-size:var(--fs-small);color:var(--fg3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.list-row-end{flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:var(--s-1);}
.clamp-3{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;}
/* the sentence a section says instead of a blank box — sits inside a list or
   a section that has nothing in it right now, never the whole page */
.empty-inline{padding:var(--s-3) 0;}
.empty-inline .et{font-size:var(--fs-body);color:var(--fg2);}
.empty-inline .es{font-size:var(--fs-small);color:var(--fg3);margin-top:2px;}
/* a row that opens a sheet AND carries its own Done/Snooze buttons cannot be a
   button itself — a button may never contain another button. This wraps just
   the title/reason/meta, inside .list-row-main, so the reading area opens the
   sheet while .row-acts sits beside it as its own, separate controls. */
.list-row-open{display:block;width:100%;text-align:left;background:none;border:none;padding:0;color:inherit;font:inherit;cursor:pointer;}
/* Done / Snooze — always on a phone (there is no hover), revealed on hover or
   keyboard focus on a desk */
.row-acts{display:flex;gap:var(--s-2);flex-wrap:wrap;margin-top:var(--s-2);}
/* hidden until hover or keyboard focus on a desk — see responsive.css. Always
   shown below that width, because a phone has no hover. */

/* ---- MONEY (a label/amount line, and the one big figure a screen gets) ---- */
.money-line{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-3);font-size:var(--fs-body);}
.money-line + .money-line{margin-top:var(--s-2);}
.money-line .lbl{color:var(--fg2);}
.money-big{font-size:var(--fs-title);line-height:var(--lh-tight);}
/* every rupee figure carries this, and the hide-amounts eye blurs it — a blur
   rather than a swap so the page keeps its shape and nothing jumps back on */
.mny{transition:filter var(--dur) var(--ease);}
html[data-mask] .mny{filter:blur(6px);user-select:none;}

/* ---- SUBHEAD — a label inside a section that groups several lists under
   one h2 (Money's "Going out", "Clients · N") ---- */
.subhead{font-size:var(--fs-small);color:var(--fg2);margin:var(--s-4) 0 var(--s-2);}
.subhead:first-child{margin-top:0;}

/* ---- SECTION HEADER, with a count ---- */
.section{display:flex;flex-direction:column;gap:var(--s-3);}
.section-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--s-3);}
.section-head h2{font-size:var(--fs-heading);font-weight:400;line-height:var(--lh-snug);}
.section-count{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--fg3);font-variant-numeric:tabular-nums;}

/* ---- MORNING LINE ---- */
.morning{display:flex;flex-direction:column;gap:var(--s-1);}
.morning .mh{font-size:var(--fs-heading);line-height:var(--lh-snug);}
.morning .mc{font-size:var(--fs-small);color:var(--fg2);}

/* ---- FOLD — a styled details/summary. Closed by default, an arrow the only hint. ---- */
.fold{border:1px solid var(--border);border-radius:var(--r-box);background:var(--bg);}
.fold summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--s-2);padding:var(--s-3) var(--s-4);font-size:var(--fs-small);color:var(--fg2);}
.fold summary::-webkit-details-marker{display:none;}
.fold summary .lbl{flex:1;min-width:0;}
.fold summary::after{content:"";flex:0 0 auto;width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);transition:transform var(--dur) var(--ease);}
.fold[open] summary::after{transform:rotate(-135deg);}
.fold .fold-body{padding:0 var(--s-4) var(--s-4);}

/* ---- RULE ROW / ADD FORM / RULEBOOK (Settings) ---- */
.rule-row{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-2) 0;border-bottom:1px solid var(--border);}
.rule-row:last-child{border-bottom:none;}
.rule-row .rv{flex:1;min-width:0;font-size:var(--fs-body);overflow-wrap:break-word;}
.rule-row .rv .arrow{color:var(--fg3);}
.rule-row .rn{display:block;font-size:var(--fs-caption);color:var(--fg3);margin-top:2px;}
.rule-remove{flex:0 0 auto;width:var(--hit);height:var(--hit);display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--fg3);cursor:pointer;border-radius:50%;transition:color var(--dur) var(--ease),background var(--dur) var(--ease);}
.rule-remove:hover{color:var(--no);background:var(--bg2);}
.rule-add{display:flex;flex-direction:column;gap:var(--s-3);margin-top:var(--s-3);padding-top:var(--s-3);border-top:1px solid var(--border);}
/* the closed state of a list: one quiet row, not three open inputs */
.rule-add-toggle{display:flex;align-items:center;width:100%;min-height:var(--hit);margin-top:var(--s-1);padding:0;background:none;border:none;color:var(--fg3);font-size:var(--fs-small);text-align:left;cursor:pointer;transition:color var(--dur) var(--ease);}
.rule-add-toggle:hover{color:var(--fg2);}
/* a quiet box of Perch's own words, pre-wrap, scrolling inside itself so it
   never grows the page — the rulebook, and a draft's body wherever it previews */
.textbox{background:var(--bg);border:1px solid var(--border);border-radius:var(--r-box);padding:var(--s-4);max-height:280px;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;font-size:var(--fs-body);color:var(--fg2);line-height:1.6;white-space:pre-wrap;overflow-wrap:break-word;}

/* ---- SETTINGS "LOOK" OPTIONS (Auto / Light / Dark) ---- */
.set-opt{border:1px solid var(--border);color:var(--fg2);padding:9px 16px;font-size:var(--fs-small);cursor:pointer;background:none;font-family:var(--font-body);border-radius:var(--r-pill);display:inline-flex;align-items:center;justify-content:center;min-height:var(--hit);transition:background var(--dur) var(--ease),color var(--dur) var(--ease),border-color var(--dur) var(--ease);}
.set-opt:hover{color:var(--fg);border-color:var(--border2);}
.set-opt.on{background:var(--fg);color:var(--canvas);border-color:var(--fg);}
.set-optrow{display:flex;gap:var(--s-2);flex-wrap:wrap;}
.set-err{font-size:var(--fs-small);color:var(--no);margin-top:var(--s-2);}
.set-logout{color:var(--fg2);}
.set-logout:hover{color:var(--no);border-color:var(--no);}

/* ---- THE SCREEN — its own sections, and the quiet stamp under them.
   Stacked on a phone; @media(min-width:1080px) in responsive.css turns this
   into two native CSS columns on a wide desk, reading order unchanged.
   #wall itself carries the same gap, so the morning line sits as far from
   Robots as Robots sits from Needs you — one token, used everywhere. ---- */
#wall{display:flex;flex-direction:column;gap:var(--page-gap);}
.wall-cols{display:flex;flex-direction:column;gap:var(--page-gap);}
.stamp{font-size:var(--fs-caption);color:var(--fg3);text-align:center;}

/* ---- BAR — the sticky top bar. status-bar-style is black-translucent (see
   app.html), so this bar paints under the phone's own status bar/clock on an
   installed app; the extra padding-top is what keeps the mark and the
   buttons clear of it. env() with a 0px fallback: a normal browser tab has
   no inset, so nothing here moves there. ---- */
.bar{position:sticky;top:0;z-index:var(--z-sticky);display:flex;align-items:center;gap:var(--s-3);padding:var(--s-3) var(--page-pad-x);padding-top:calc(var(--s-3) + env(safe-area-inset-top, 0px));background:var(--glass);backdrop-filter:var(--glass-fx);-webkit-backdrop-filter:var(--glass-fx);border-bottom:1px solid var(--hairline);}
.bar h1{font-size:var(--fs-heading);font-weight:400;line-height:1;display:flex;align-items:center;gap:var(--s-2);}
.bar h1 img{display:block;}

/* ---- THE FOUR SCREEN STATES ---- */
.banner{display:flex;align-items:flex-start;gap:var(--s-2);padding:var(--s-3) var(--s-4);font-size:var(--fs-small);border:1px solid currentColor;border-radius:var(--radius);color:var(--fg2);}
.banner-error{color:var(--ink-red);}
.skeleton{background:linear-gradient(90deg,var(--bg2) 25%,var(--bg3) 50%,var(--bg2) 75%);background-size:200% 100%;border-radius:var(--r-sm);animation:hdwShimmer 1.4s linear infinite;}
@keyframes hdwShimmer{from{background-position:200% 0;}to{background-position:-200% 0;}}
.skeleton-line{height:12px;margin-bottom:var(--s-2);}
.skeleton-line:last-child{width:60%;margin-bottom:0;}
.skeleton-title{height:18px;width:40%;margin-bottom:var(--s-3);}
